@kitten-science/kitten-scientists 2.0.0-beta.11-dev → 2.0.0-beta.11-dev.20250518
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/KittenScientists.d.ts +1 -0
- package/lib/KittenScientists.d.ts.map +1 -1
- package/lib/KittenScientists.js +0 -1
- package/lib/KittenScientists.js.map +1 -1
- package/lib/entrypoint-loader.d.ts +5 -0
- package/lib/entrypoint-loader.d.ts.map +1 -0
- package/lib/entrypoint-loader.js +17 -0
- package/lib/entrypoint-loader.js.map +1 -0
- package/output/kitten-scientists-0.0.0-ci.min.user.js +37 -0
- package/output/kitten-scientists-0.0.0-ci.user.js +15416 -0
- package/output/kitten-scientists-loader-0.0.0-ci.min.user.js +16 -0
- package/output/kitten-scientists-loader-0.0.0-ci.user.js +109 -0
- package/output/kitten-scientists.inject.js +1 -1
- package/output/kitten-scientists.min.inject.js +23 -0
- package/package.json +3 -3
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// ==UserScript==
|
|
2
|
+
// @name Kitten Scientists
|
|
3
|
+
// @description Add-on for the wonderful incremental browser game: https://kittensgame.com/web/
|
|
4
|
+
// @namespace https://kitten-science.com/
|
|
5
|
+
// @author Oliver Salzburg <oliver.salzburg@gmail.com>
|
|
6
|
+
// @icon https://kitten-science.com/assets/images/organization-logo64.png
|
|
7
|
+
// @match https://kittensgame.com/web/
|
|
8
|
+
// @match https://kittensgame.com/beta/
|
|
9
|
+
// @match https://kittensgame.com/alpha/
|
|
10
|
+
// @downloadURL https://kitten-science.com/fixed.js
|
|
11
|
+
// @homepageURL https://github.com/kitten-science/kitten-scientists
|
|
12
|
+
// @updateURL https://kitten-science.com/fixed.min.js
|
|
13
|
+
// @version 0.0.0-ci
|
|
14
|
+
// @grant none
|
|
15
|
+
// ==/UserScript==
|
|
16
|
+
(function(factory) {
|
|
17
|
+
typeof define === "function" && define.amd ? define(factory) : factory();
|
|
18
|
+
})(function() {
|
|
19
|
+
"use strict";var __defProp = Object.defineProperty;
|
|
20
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
21
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
22
|
+
|
|
23
|
+
function isNil(subject) {
|
|
24
|
+
return subject === null || subject === void 0;
|
|
25
|
+
}
|
|
26
|
+
const redirectErrorsToConsole = (console2) => {
|
|
27
|
+
const printErrorsToConsole = (error) => {
|
|
28
|
+
console2.error(error);
|
|
29
|
+
};
|
|
30
|
+
return printErrorsToConsole;
|
|
31
|
+
};
|
|
32
|
+
class AbstractError extends Error {
|
|
33
|
+
/**
|
|
34
|
+
* Constructs a new {@linkcode AbstractError}.
|
|
35
|
+
* @param code - The main identification code for the error.
|
|
36
|
+
* @param message - The main error message.
|
|
37
|
+
* @param status - The HTTP status code to return.
|
|
38
|
+
*/
|
|
39
|
+
constructor(code, message, status) {
|
|
40
|
+
super(message);
|
|
41
|
+
/**
|
|
42
|
+
* The HTTP status code to associate with this error.
|
|
43
|
+
*/
|
|
44
|
+
__publicField(this, "status");
|
|
45
|
+
/**
|
|
46
|
+
* An application-unique, readable error code.
|
|
47
|
+
*/
|
|
48
|
+
__publicField(this, "code");
|
|
49
|
+
this.code = code;
|
|
50
|
+
this.name = "AbstractError";
|
|
51
|
+
this.status = status;
|
|
52
|
+
if (typeof Error.captureStackTrace !== "undefined") {
|
|
53
|
+
Error.captureStackTrace(this, AbstractError);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Checks if an object is an instance of {@linkcode AbstractError}, or one of its subclasses.
|
|
58
|
+
* @param error - The object to check.
|
|
59
|
+
* @param allowForeignModule - Only check for similar looking error codes.
|
|
60
|
+
* You're going to want to use this if you're dealing with a setup where
|
|
61
|
+
* multiple versions of js-utils are loaded.
|
|
62
|
+
* @returns `true` if the object is an {@linkcode AbstractError}, `false` otherwise.
|
|
63
|
+
*/
|
|
64
|
+
static isAbstractError(error, allowForeignModule = true) {
|
|
65
|
+
if (error instanceof AbstractError) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
if (allowForeignModule) {
|
|
69
|
+
const errorRecord = error;
|
|
70
|
+
if (Object(error) === error && "code" in errorRecord && typeof errorRecord.code === "string") {
|
|
71
|
+
const codedError = error;
|
|
72
|
+
if (codedError.code.match(/^ERR_OS_/)) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
class InvalidOperationError extends AbstractError {
|
|
81
|
+
/**
|
|
82
|
+
* Constructs a new {@linkcode InvalidOperationError}.
|
|
83
|
+
* @param message - The main error message.
|
|
84
|
+
* @param status - The HTTP status code to return.
|
|
85
|
+
*/
|
|
86
|
+
constructor(message, status = 400) {
|
|
87
|
+
super("ERR_OS_INVALID_OPERATION", message, status);
|
|
88
|
+
this.name = "InvalidOperationError";
|
|
89
|
+
if (typeof Error.captureStackTrace !== "undefined") {
|
|
90
|
+
Error.captureStackTrace(this, InvalidOperationError);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
(async () => {
|
|
95
|
+
const existingLoader = document.querySelector("#ks-loader-singleton");
|
|
96
|
+
if (!isNil(existingLoader)) {
|
|
97
|
+
throw new InvalidOperationError(
|
|
98
|
+
"The Kitten Science script loader was already created. This is unexpected."
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
if (typeof GM !== "undefined") {
|
|
102
|
+
const nodeScript = document.createElement("script");
|
|
103
|
+
nodeScript.id = "ks-loader-singleton";
|
|
104
|
+
nodeScript.textContent = '(function(factory) {\n typeof define === "function" && define.amd ? define(["dojo"], factory) : factory();\n})(function() {\n "use strict";var __defProp = Object.defineProperty;\nvar __typeError = (msg) => {\n throw TypeError(msg);\n};\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);\nvar __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);\nvar __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));\nvar __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\nvar __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);\n\n var _options, _upgrade, _baseBuilding, _building, _stage, _building2, _variant, _policy, _tech, _mission, _building3, _variant2, _upgrade2, _resource, _resource2, _baseBuilding2, _building4, _stage2, _building5, _variant3, _resource3, _building6, _building7, _variant4, _upgrade3, _building8, _variant5, _race, _race2, _require;\n function isNil(subject) {\n return subject === null || subject === void 0;\n }\n function is(subject, Prototype) {\n return !isNil(subject) && subject instanceof Prototype;\n }\n class UnexpectedNilError extends Error {\n /**\n * Constructs a new {@linkcode UnexpectedNilError}.\n * @param message - The error message.\n */\n constructor(message = "unexpected nil value") {\n super(message);\n }\n }\n function mustExist(subject, errorMessage) {\n if (isNil(subject)) {\n throw new UnexpectedNilError(errorMessage);\n }\n return subject;\n }\n function coalesceArray(nilables, to) {\n const result = new Array();\n for (const nilable of nilables) {\n if (!isNil(nilable)) {\n result.push(nilable);\n } else if (!isNil(to)) {\n result.push(to);\n }\n }\n return result;\n }\n const redirectErrorsToConsole = (console2) => {\n const printErrorsToConsole = (error) => {\n console2.error(error);\n };\n return printErrorsToConsole;\n };\n class AbstractError extends Error {\n /**\n * Constructs a new {@linkcode AbstractError}.\n * @param code - The main identification code for the error.\n * @param message - The main error message.\n * @param status - The HTTP status code to return.\n */\n constructor(code, message, status) {\n super(message);\n /**\n * The HTTP status code to associate with this error.\n */\n __publicField(this, "status");\n /**\n * An application-unique, readable error code.\n */\n __publicField(this, "code");\n this.code = code;\n this.name = "AbstractError";\n this.status = status;\n if (typeof Error.captureStackTrace !== "undefined") {\n Error.captureStackTrace(this, AbstractError);\n }\n }\n /**\n * Checks if an object is an instance of {@linkcode AbstractError}, or one of its subclasses.\n * @param error - The object to check.\n * @param allowForeignModule - Only check for similar looking error codes.\n * You\'re going to want to use this if you\'re dealing with a setup where\n * multiple versions of js-utils are loaded.\n * @returns `true` if the object is an {@linkcode AbstractError}, `false` otherwise.\n */\n static isAbstractError(error, allowForeignModule = true) {\n if (error instanceof AbstractError) {\n return true;\n }\n if (allowForeignModule) {\n const errorRecord = error;\n if (Object(error) === error && "code" in errorRecord && typeof errorRecord.code === "string") {\n const codedError = error;\n if (codedError.code.match(/^ERR_OS_/)) {\n return true;\n }\n }\n }\n return false;\n }\n }\n class InvalidOperationError extends AbstractError {\n /**\n * Constructs a new {@linkcode InvalidOperationError}.\n * @param message - The main error message.\n * @param status - The HTTP status code to return.\n */\n constructor(message, status = 400) {\n super("ERR_OS_INVALID_OPERATION", message, status);\n this.name = "InvalidOperationError";\n if (typeof Error.captureStackTrace !== "undefined") {\n Error.captureStackTrace(this, InvalidOperationError);\n }\n }\n }\n var debug_1;\n var hasRequiredDebug;\n function requireDebug() {\n if (hasRequiredDebug) return debug_1;\n hasRequiredDebug = 1;\n const debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\\bsemver\\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {\n };\n debug_1 = debug;\n return debug_1;\n }\n var constants;\n var hasRequiredConstants;\n function requireConstants() {\n if (hasRequiredConstants) return constants;\n hasRequiredConstants = 1;\n const SEMVER_SPEC_VERSION = "2.0.0";\n const MAX_LENGTH = 256;\n const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */\n 9007199254740991;\n const MAX_SAFE_COMPONENT_LENGTH = 16;\n const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6;\n const RELEASE_TYPES = [\n "major",\n "premajor",\n "minor",\n "preminor",\n "patch",\n "prepatch",\n "prerelease"\n ];\n constants = {\n MAX_LENGTH,\n MAX_SAFE_COMPONENT_LENGTH,\n MAX_SAFE_BUILD_LENGTH,\n MAX_SAFE_INTEGER,\n RELEASE_TYPES,\n SEMVER_SPEC_VERSION,\n FLAG_INCLUDE_PRERELEASE: 1,\n FLAG_LOOSE: 2\n };\n return constants;\n }\n var re = { exports: {} };\n var hasRequiredRe;\n function requireRe() {\n if (hasRequiredRe) return re.exports;\n hasRequiredRe = 1;\n (function(module, exports) {\n const {\n MAX_SAFE_COMPONENT_LENGTH,\n MAX_SAFE_BUILD_LENGTH,\n MAX_LENGTH\n } = requireConstants();\n const debug = requireDebug();\n exports = module.exports = {};\n const re2 = exports.re = [];\n const safeRe = exports.safeRe = [];\n const src = exports.src = [];\n const safeSrc = exports.safeSrc = [];\n const t = exports.t = {};\n let R = 0;\n const LETTERDASHNUMBER = "[a-zA-Z0-9-]";\n const safeRegexReplacements = [\n ["\\\\s", 1],\n ["\\\\d", MAX_LENGTH],\n [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH]\n ];\n const makeSafeRegex = (value) => {\n for (const [token, max] of safeRegexReplacements) {\n value = value.split(`${token}*`).join(`${token}{0,${max}}`).split(`${token}+`).join(`${token}{1,${max}}`);\n }\n return value;\n };\n const createToken = (name, value, isGlobal) => {\n const safe = makeSafeRegex(value);\n const index = R++;\n debug(name, index, value);\n t[name] = index;\n src[index] = value;\n safeSrc[index] = safe;\n re2[index] = new RegExp(value, isGlobal ? "g" : void 0);\n safeRe[index] = new RegExp(safe, isGlobal ? "g" : void 0);\n };\n createToken("NUMERICIDENTIFIER", "0|[1-9]\\\\d*");\n createToken("NUMERICIDENTIFIERLOOSE", "\\\\d+");\n createToken("NONNUMERICIDENTIFIER", `\\\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`);\n createToken("MAINVERSION", `(${src[t.NUMERICIDENTIFIER]})\\\\.(${src[t.NUMERICIDENTIFIER]})\\\\.(${src[t.NUMERICIDENTIFIER]})`);\n createToken("MAINVERSIONLOOSE", `(${src[t.NUMERICIDENTIFIERLOOSE]})\\\\.(${src[t.NUMERICIDENTIFIERLOOSE]})\\\\.(${src[t.NUMERICIDENTIFIERLOOSE]})`);\n createToken("PRERELEASEIDENTIFIER", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIER]})`);\n createToken("PRERELEASEIDENTIFIERLOOSE", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIERLOOSE]})`);\n createToken("PRERELEASE", `(?:-(${src[t.PRERELEASEIDENTIFIER]}(?:\\\\.${src[t.PRERELEASEIDENTIFIER]})*))`);\n createToken("PRERELEASELOOSE", `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]}(?:\\\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);\n createToken("BUILDIDENTIFIER", `${LETTERDASHNUMBER}+`);\n createToken("BUILD", `(?:\\\\+(${src[t.BUILDIDENTIFIER]}(?:\\\\.${src[t.BUILDIDENTIFIER]})*))`);\n createToken("FULLPLAIN", `v?${src[t.MAINVERSION]}${src[t.PRERELEASE]}?${src[t.BUILD]}?`);\n createToken("FULL", `^${src[t.FULLPLAIN]}$`);\n createToken("LOOSEPLAIN", `[v=\\\\s]*${src[t.MAINVERSIONLOOSE]}${src[t.PRERELEASELOOSE]}?${src[t.BUILD]}?`);\n createToken("LOOSE", `^${src[t.LOOSEPLAIN]}$`);\n createToken("GTLT", "((?:<|>)?=?)");\n createToken("XRANGEIDENTIFIERLOOSE", `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\\\*`);\n createToken("XRANGEIDENTIFIER", `${src[t.NUMERICIDENTIFIER]}|x|X|\\\\*`);\n createToken("XRANGEPLAIN", `[v=\\\\s]*(${src[t.XRANGEIDENTIFIER]})(?:\\\\.(${src[t.XRANGEIDENTIFIER]})(?:\\\\.(${src[t.XRANGEIDENTIFIER]})(?:${src[t.PRERELEASE]})?${src[t.BUILD]}?)?)?`);\n createToken("XRANGEPLAINLOOSE", `[v=\\\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})(?:\\\\.(${src[t.XRANGEIDENTIFIERLOOSE]})(?:\\\\.(${src[t.XRANGEIDENTIFIERLOOSE]})(?:${src[t.PRERELEASELOOSE]})?${src[t.BUILD]}?)?)?`);\n createToken("XRANGE", `^${src[t.GTLT]}\\\\s*${src[t.XRANGEPLAIN]}$`);\n createToken("XRANGELOOSE", `^${src[t.GTLT]}\\\\s*${src[t.XRANGEPLAINLOOSE]}$`);\n createToken("COERCEPLAIN", `${"(^|[^\\\\d])(\\\\d{1,"}${MAX_SAFE_COMPONENT_LENGTH}})(?:\\\\.(\\\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:\\\\.(\\\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`);\n createToken("COERCE", `${src[t.COERCEPLAIN]}(?:$|[^\\\\d])`);\n createToken("COERCEFULL", src[t.COERCEPLAIN] + `(?:${src[t.PRERELEASE]})?(?:${src[t.BUILD]})?(?:$|[^\\\\d])`);\n createToken("COERCERTL", src[t.COERCE], true);\n createToken("COERCERTLFULL", src[t.COERCEFULL], true);\n createToken("LONETILDE", "(?:~>?)");\n createToken("TILDETRIM", `(\\\\s*)${src[t.LONETILDE]}\\\\s+`, true);\n exports.tildeTrimReplace = "$1~";\n createToken("TILDE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);\n createToken("TILDELOOSE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);\n createToken("LONECARET", "(?:\\\\^)");\n createToken("CARETTRIM", `(\\\\s*)${src[t.LONECARET]}\\\\s+`, true);\n exports.caretTrimReplace = "$1^";\n createToken("CARET", `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);\n createToken("CARETLOOSE", `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);\n createToken("COMPARATORLOOSE", `^${src[t.GTLT]}\\\\s*(${src[t.LOOSEPLAIN]})$|^$`);\n createToken("COMPARATOR", `^${src[t.GTLT]}\\\\s*(${src[t.FULLPLAIN]})$|^$`);\n createToken("COMPARATORTRIM", `(\\\\s*)${src[t.GTLT]}\\\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);\n exports.comparatorTrimReplace = "$1$2$3";\n createToken("HYPHENRANGE", `^\\\\s*(${src[t.XRANGEPLAIN]})\\\\s+-\\\\s+(${src[t.XRANGEPLAIN]})\\\\s*$`);\n createToken("HYPHENRANGELOOSE", `^\\\\s*(${src[t.XRANGEPLAINLOOSE]})\\\\s+-\\\\s+(${src[t.XRANGEPLAINLOOSE]})\\\\s*$`);\n createToken("STAR", "(<|>)?=?\\\\s*\\\\*");\n createToken("GTE0", "^\\\\s*>=\\\\s*0\\\\.0\\\\.0\\\\s*$");\n createToken("GTE0PRE", "^\\\\s*>=\\\\s*0\\\\.0\\\\.0-0\\\\s*$");\n })(re, re.exports);\n return re.exports;\n }\n var parseOptions_1;\n var hasRequiredParseOptions;\n function requireParseOptions() {\n if (hasRequiredParseOptions) return parseOptions_1;\n hasRequiredParseOptions = 1;\n const looseOption = Object.freeze({ loose: true });\n const emptyOpts = Object.freeze({});\n const parseOptions = (options) => {\n if (!options) {\n return emptyOpts;\n }\n if (typeof options !== "object") {\n return looseOption;\n }\n return options;\n };\n parseOptions_1 = parseOptions;\n return parseOptions_1;\n }\n var identifiers;\n var hasRequiredIdentifiers;\n function requireIdentifiers() {\n if (hasRequiredIdentifiers) return identifiers;\n hasRequiredIdentifiers = 1;\n const numeric = /^[0-9]+$/;\n const compareIdentifiers = (a, b) => {\n const anum = numeric.test(a);\n const bnum = numeric.test(b);\n if (anum && bnum) {\n a = +a;\n b = +b;\n }\n return a === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : 1;\n };\n const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a);\n identifiers = {\n compareIdentifiers,\n rcompareIdentifiers\n };\n return identifiers;\n }\n var semver;\n var hasRequiredSemver;\n function requireSemver() {\n if (hasRequiredSemver) return semver;\n hasRequiredSemver = 1;\n const debug = requireDebug();\n const { MAX_LENGTH, MAX_SAFE_INTEGER } = requireConstants();\n const { safeRe: re2, t } = requireRe();\n const parseOptions = requireParseOptions();\n const { compareIdentifiers } = requireIdentifiers();\n class SemVer {\n constructor(version, options) {\n options = parseOptions(options);\n if (version instanceof SemVer) {\n if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) {\n return version;\n } else {\n version = version.version;\n }\n } else if (typeof version !== "string") {\n throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`);\n }\n if (version.length > MAX_LENGTH) {\n throw new TypeError(\n `version is longer than ${MAX_LENGTH} characters`\n );\n }\n debug("SemVer", version, options);\n this.options = options;\n this.loose = !!options.loose;\n this.includePrerelease = !!options.includePrerelease;\n const m = version.trim().match(options.loose ? re2[t.LOOSE] : re2[t.FULL]);\n if (!m) {\n throw new TypeError(`Invalid Version: ${version}`);\n }\n this.raw = version;\n this.major = +m[1];\n this.minor = +m[2];\n this.patch = +m[3];\n if (this.major > MAX_SAFE_INTEGER || this.major < 0) {\n throw new TypeError("Invalid major version");\n }\n if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {\n throw new TypeError("Invalid minor version");\n }\n if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {\n throw new TypeError("Invalid patch version");\n }\n if (!m[4]) {\n this.prerelease = [];\n } else {\n this.prerelease = m[4].split(".").map((id) => {\n if (/^[0-9]+$/.test(id)) {\n const num = +id;\n if (num >= 0 && num < MAX_SAFE_INTEGER) {\n return num;\n }\n }\n return id;\n });\n }\n this.build = m[5] ? m[5].split(".") : [];\n this.format();\n }\n format() {\n this.version = `${this.major}.${this.minor}.${this.patch}`;\n if (this.prerelease.length) {\n this.version += `-${this.prerelease.join(".")}`;\n }\n return this.version;\n }\n toString() {\n return this.version;\n }\n compare(other) {\n debug("SemVer.compare", this.version, this.options, other);\n if (!(other instanceof SemVer)) {\n if (typeof other === "string" && other === this.version) {\n return 0;\n }\n other = new SemVer(other, this.options);\n }\n if (other.version === this.version) {\n return 0;\n }\n return this.compareMain(other) || this.comparePre(other);\n }\n compareMain(other) {\n if (!(other instanceof SemVer)) {\n other = new SemVer(other, this.options);\n }\n return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);\n }\n comparePre(other) {\n if (!(other instanceof SemVer)) {\n other = new SemVer(other, this.options);\n }\n if (this.prerelease.length && !other.prerelease.length) {\n return -1;\n } else if (!this.prerelease.length && other.prerelease.length) {\n return 1;\n } else if (!this.prerelease.length && !other.prerelease.length) {\n return 0;\n }\n let i = 0;\n do {\n const a = this.prerelease[i];\n const b = other.prerelease[i];\n debug("prerelease compare", i, a, b);\n if (a === void 0 && b === void 0) {\n return 0;\n } else if (b === void 0) {\n return 1;\n } else if (a === void 0) {\n return -1;\n } else if (a === b) {\n continue;\n } else {\n return compareIdentifiers(a, b);\n }\n } while (++i);\n }\n compareBuild(other) {\n if (!(other instanceof SemVer)) {\n other = new SemVer(other, this.options);\n }\n let i = 0;\n do {\n const a = this.build[i];\n const b = other.build[i];\n debug("build compare", i, a, b);\n if (a === void 0 && b === void 0) {\n return 0;\n } else if (b === void 0) {\n return 1;\n } else if (a === void 0) {\n return -1;\n } else if (a === b) {\n continue;\n } else {\n return compareIdentifiers(a, b);\n }\n } while (++i);\n }\n // preminor will bump the version up to the next minor release, and immediately\n // down to pre-release. premajor and prepatch work the same way.\n inc(release, identifier, identifierBase) {\n if (release.startsWith("pre")) {\n if (!identifier && identifierBase === false) {\n throw new Error("invalid increment argument: identifier is empty");\n }\n if (identifier) {\n const match2 = `-${identifier}`.match(this.options.loose ? re2[t.PRERELEASELOOSE] : re2[t.PRERELEASE]);\n if (!match2 || match2[1] !== identifier) {\n throw new Error(`invalid identifier: ${identifier}`);\n }\n }\n }\n switch (release) {\n case "premajor":\n this.prerelease.length = 0;\n this.patch = 0;\n this.minor = 0;\n this.major++;\n this.inc("pre", identifier, identifierBase);\n break;\n case "preminor":\n this.prerelease.length = 0;\n this.patch = 0;\n this.minor++;\n this.inc("pre", identifier, identifierBase);\n break;\n case "prepatch":\n this.prerelease.length = 0;\n this.inc("patch", identifier, identifierBase);\n this.inc("pre", identifier, identifierBase);\n break;\n // If the input is a non-prerelease version, this acts the same as\n // prepatch.\n case "prerelease":\n if (this.prerelease.length === 0) {\n this.inc("patch", identifier, identifierBase);\n }\n this.inc("pre", identifier, identifierBase);\n break;\n case "release":\n if (this.prerelease.length === 0) {\n throw new Error(`version ${this.raw} is not a prerelease`);\n }\n this.prerelease.length = 0;\n break;\n case "major":\n if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) {\n this.major++;\n }\n this.minor = 0;\n this.patch = 0;\n this.prerelease = [];\n break;\n case "minor":\n if (this.patch !== 0 || this.prerelease.length === 0) {\n this.minor++;\n }\n this.patch = 0;\n this.prerelease = [];\n break;\n case "patch":\n if (this.prerelease.length === 0) {\n this.patch++;\n }\n this.prerelease = [];\n break;\n // This probably shouldn\'t be used publicly.\n // 1.0.0 \'pre\' would become 1.0.0-0 which is the wrong direction.\n case "pre": {\n const base = Number(identifierBase) ? 1 : 0;\n if (this.prerelease.length === 0) {\n this.prerelease = [base];\n } else {\n let i = this.prerelease.length;\n while (--i >= 0) {\n if (typeof this.prerelease[i] === "number") {\n this.prerelease[i]++;\n i = -2;\n }\n }\n if (i === -1) {\n if (identifier === this.prerelease.join(".") && identifierBase === false) {\n throw new Error("invalid increment argument: identifier already exists");\n }\n this.prerelease.push(base);\n }\n }\n if (identifier) {\n let prerelease = [identifier, base];\n if (identifierBase === false) {\n prerelease = [identifier];\n }\n if (compareIdentifiers(this.prerelease[0], identifier) === 0) {\n if (isNaN(this.prerelease[1])) {\n this.prerelease = prerelease;\n }\n } else {\n this.prerelease = prerelease;\n }\n }\n break;\n }\n default:\n throw new Error(`invalid increment argument: ${release}`);\n }\n this.raw = this.format();\n if (this.build.length) {\n this.raw += `+${this.build.join(".")}`;\n }\n return this;\n }\n }\n semver = SemVer;\n return semver;\n }\n var compare_1;\n var hasRequiredCompare;\n function requireCompare() {\n if (hasRequiredCompare) return compare_1;\n hasRequiredCompare = 1;\n const SemVer = requireSemver();\n const compare = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose));\n compare_1 = compare;\n return compare_1;\n }\n var gt_1;\n var hasRequiredGt;\n function requireGt() {\n if (hasRequiredGt) return gt_1;\n hasRequiredGt = 1;\n const compare = requireCompare();\n const gt = (a, b, loose) => compare(a, b, loose) > 0;\n gt_1 = gt;\n return gt_1;\n }\n requireGt();\n class InternalError extends AbstractError {\n /**\n * Constructs a new {@linkcode InternalError}.\n * @param message - The main error message.\n * @param status - The HTTP status code to return.\n */\n constructor(message, status = 500) {\n super("ERR_OS_INTERNAL", message, status);\n this.name = "InternalError";\n if (typeof Error.captureStackTrace !== "undefined") {\n Error.captureStackTrace(this, InternalError);\n }\n }\n /**\n * Converts an error into an {@linkcode InternalError}.\n * @param error - The error to convert.\n * @returns An {@linkcode InternalError} that represents the given error.\n */\n static fromError(error) {\n const internalError = new InternalError(error.message);\n Object.assign(internalError, error, new InternalError(error.message));\n internalError.stack = error.stack;\n return internalError;\n }\n }\n class UnknownError extends AbstractError {\n /**\n * Constructs a new {@linkcode UnknownError}.\n * @param message - The main error message.\n * @param status - The HTTP status code to return.\n */\n constructor(message, status = 500) {\n super("ERR_OS_UNKNOWN", message, status);\n this.name = "UnknownError";\n if (typeof Error.captureStackTrace !== "undefined") {\n Error.captureStackTrace(this, UnknownError);\n }\n }\n }\n const isError = (subject) => {\n return subject instanceof Error || Object.prototype.toString.call(subject) === "[object Error]";\n };\n const unknownToError = (subject) => {\n if (AbstractError.isAbstractError(subject)) {\n return subject;\n }\n if (isError(subject)) {\n return InternalError.fromError(subject);\n }\n return new UnknownError(String(subject));\n };\n const measure = (context) => {\n const entry = performance.now();\n return [context(), performance.now() - entry];\n };\n const measureAsync = async (context) => {\n const entry = performance.now();\n return [await context(), performance.now() - entry];\n };\n const difference = (a, b) => {\n return a.filter((x) => !b.includes(x));\n };\n const cl = (...args) => [\n "👩🔬",\n ...args.filter((arg) => arg !== "").flatMap((maybeError) => {\n if (is(maybeError, Error)) {\n const error = maybeError;\n return [error.name, error.message, error.stack];\n }\n return maybeError;\n })\n ];\n function objectEntries(subject) {\n return Object.entries(subject);\n }\n function consumeEntriesPedantic(subject, source, consumer) {\n if (isNil(source)) {\n console.warn(...cl("No source data was provided."));\n return subject;\n }\n for (const [key, value] of objectEntries(subject)) {\n if (!(key in source)) {\n console.info(...cl(`Entry \'${key}\' is missing in source. Using default value.`));\n }\n consumer(value, source[key]);\n }\n for (const [key] of objectEntries(source)) {\n if (!(key in subject)) {\n console.warn(\n ...cl(\n `Entry \'${key}\' was found in source, but it is not expected by the subject schema. This entry will be ignored.`\n )\n );\n }\n }\n return subject;\n }\n class Unique {\n constructor(elem) {\n __publicField(this, "_elem");\n this._elem = structuredClone(elem);\n }\n unwrap() {\n return structuredClone(this._elem);\n }\n replace(elem) {\n this._elem = structuredClone(elem);\n }\n toJSON() {\n return this.unwrap();\n }\n }\n function ucfirst(input) {\n return input.charAt(0).toUpperCase() + input.slice(1);\n }\n function roundToTwo(input) {\n return Math.round(input * 100) / 100;\n }\n function negativeOneToInfinity(value) {\n return value === -1 ? Number.POSITIVE_INFINITY : value;\n }\n class BulkPurchaseHelper {\n constructor(host, workshopManager) {\n __publicField(this, "_host");\n __publicField(this, "_workshopManager");\n this._host = host;\n this._workshopManager = workshopManager;\n }\n /**\n * Take a hash of potential builds and determine how many of them can be built.\n *\n * @param builds - All potential builds.\n * @param metaData - The metadata for the potential builds.\n * @param sectionTrigger - The configured trigger threshold for the section of these builds.\n * @param sourceTab - The tab these builds originate from.\n * @returns All the possible builds.\n */\n bulk(builds, metaData, sectionTrigger, sourceTab) {\n const potentialBuilds = [];\n let counter = 0;\n for (const [name, build] of objectEntries(builds)) {\n const trigger = Engine.evaluateSubSectionTrigger(sectionTrigger, build.trigger);\n const buildMetaData = mustExist(metaData[name]);\n if (!build.enabled || trigger < 0) {\n continue;\n }\n if ("tHidden" in buildMetaData && buildMetaData.tHidden === true) {\n continue;\n }\n if ("rHidden" in buildMetaData && buildMetaData.rHidden === true) {\n continue;\n }\n if (buildMetaData.unlocked === false) {\n continue;\n }\n if (!isNil(build.max) && -1 < build.max && build.max <= buildMetaData.val) {\n continue;\n }\n if (name === "cryochambers" && (mustExist(this._host.game.time.getVSU("usedCryochambers")).val > 0 || this._host.game.bld.getBuildingExt("chronosphere").meta.val <= buildMetaData.val)) {\n continue;\n }\n if (name === "ressourceRetrieval" && buildMetaData.val >= 100) {\n continue;\n }\n const prices = mustExist(\n this._isStagedBuild(buildMetaData) ? buildMetaData.stages[buildMetaData.stage].prices : buildMetaData.prices\n );\n const priceRatio = this.getPriceRatio(buildMetaData, sourceTab);\n if (!this.singleBuildPossible(buildMetaData, prices, priceRatio, sourceTab)) {\n continue;\n }\n const requiredMaterials = prices.map((price) => this._workshopManager.getResource(price.name)).filter((material) => 0 < material.maxValue);\n const allMaterialsAboveTrigger = requiredMaterials.filter((material) => material.value / material.maxValue < trigger).length === 0;\n if (allMaterialsAboveTrigger) {\n if (this._isStagedBuild(buildMetaData) && typeof build.stage !== "undefined" && build.stage !== buildMetaData.stage) {\n continue;\n }\n const itemPrices = [];\n const pricesDiscount = this._host.game.getLimitedDR(\n this._host.game.getEffect(`${name}CostReduction`),\n 1\n );\n const priceModifier = 1 - pricesDiscount;\n for (const price of prices) {\n const resPriceDiscount = this._host.game.getLimitedDR(\n this._host.game.getEffect(`${price.name}CostReduction`),\n 1\n );\n const resPriceModifier = 1 - resPriceDiscount;\n itemPrices.push({\n name: price.name,\n val: price.val * priceModifier * resPriceModifier\n });\n }\n potentialBuilds.push({\n count: 0,\n id: name,\n label: build.label,\n limit: build.max || 0,\n name: build.baseBuilding ?? build.building,\n priceRatio,\n prices: itemPrices,\n source: sourceTab,\n spot: counter,\n val: buildMetaData.val,\n variant: build.variant\n });\n counter++;\n }\n }\n if (potentialBuilds.length === 0) {\n return [];\n }\n const currentResourcePool = {};\n for (const res of this._host.game.resPool.resources) {\n currentResourcePool[res.name] = this._workshopManager.getValueAvailable(res.name);\n }\n let iterations = 0;\n const buildsCommitted = new Array();\n while (iterations < 1e5) {\n const candidatesThisIteration = difference(potentialBuilds, buildsCommitted);\n let buildThisIteration = 0;\n const committedThisIteration = [];\n let tempPool = { ...currentResourcePool };\n for (const committedBuild of buildsCommitted) {\n const possibleInstances = this._precalculateBuilds(\n {\n ...committedBuild,\n limit: committedBuild.val + committedBuild.count\n },\n metaData,\n tempPool\n );\n tempPool = possibleInstances.remainingResources;\n }\n for (const potentialBuild of candidatesThisIteration) {\n const targetInstanceCount = potentialBuild.count + 1;\n const possibleInstances = this._precalculateBuilds(\n {\n ...potentialBuild,\n limit: Math.min(\n negativeOneToInfinity(potentialBuild.limit),\n potentialBuild.val + targetInstanceCount\n )\n },\n metaData,\n tempPool\n );\n if (possibleInstances.count < targetInstanceCount) {\n committedThisIteration.push(potentialBuild);\n continue;\n }\n potentialBuild.count = targetInstanceCount;\n tempPool = possibleInstances.remainingResources;\n buildThisIteration++;\n }\n buildsCommitted.push(...committedThisIteration);\n iterations++;\n if (buildThisIteration === 0) {\n break;\n }\n }\n console.debug(...cl(`Took \'${iterations}\' iterations to evaluate bulk build request.`));\n return buildsCommitted;\n }\n /**\n * Calculate how many of a given build item build be built with the given resources.\n *\n * @param buildCacheItem The item to build.\n * @param buildCacheItem.id ?\n * @param buildCacheItem.name ?\n * @param buildCacheItem.count ?\n * @param buildCacheItem.spot ?\n * @param buildCacheItem.prices ?\n * @param buildCacheItem.priceRatio ?\n * @param buildCacheItem.source ?\n * @param buildCacheItem.limit ?\n * @param buildCacheItem.val ?\n * @param metaData The metadata for the potential builds.\n * @param resources The currently available resources.\n * @returns The number of items that could be built. If this is non-zero, the `resources` will have been adjusted\n * to reflect the number of builds made.\n */\n _precalculateBuilds(buildCacheItem, metaData, resources = {}) {\n let buildsPossible = 0;\n const tempPool = Object.assign({}, resources);\n const buildMetaData = mustExist(metaData[buildCacheItem.id]);\n const prices = buildCacheItem.prices;\n const priceRatio = buildCacheItem.priceRatio;\n const source = buildCacheItem.source;\n let maxItemsBuilt = false;\n if (prices.length === 0) {\n return { count: 0, remainingResources: tempPool };\n }\n while (!maxItemsBuilt) {\n for (let priceIndex = 0; priceIndex < prices.length; priceIndex++) {\n let spaceOil = false;\n let cryoKarma = false;\n let oilPrice = Number.POSITIVE_INFINITY;\n let karmaPrice = Number.POSITIVE_INFINITY;\n if (source === "Space" && prices[priceIndex].name === "oil") {\n spaceOil = true;\n const oilReductionRatio = this._host.game.getEffect("oilReductionRatio");\n oilPrice = prices[priceIndex].val * (1 - this._host.game.getLimitedDR(oilReductionRatio, 0.75));\n } else if (buildCacheItem.id === "cryochambers" && prices[priceIndex].name === "karma") {\n cryoKarma = true;\n const burnedParagonRatio = this._host.game.prestige.getBurnedParagonRatio();\n karmaPrice = prices[priceIndex].val * (1 - this._host.game.getLimitedDR(0.01 * burnedParagonRatio, 1));\n }\n if (spaceOil) {\n maxItemsBuilt = tempPool.oil < oilPrice * 1.05 ** (buildsPossible + buildMetaData.val);\n } else if (cryoKarma) {\n maxItemsBuilt = tempPool.karma < karmaPrice * priceRatio ** (buildsPossible + buildMetaData.val);\n } else {\n maxItemsBuilt = tempPool[prices[priceIndex].name] < prices[priceIndex].val * priceRatio ** (buildsPossible + buildMetaData.val);\n }\n if (maxItemsBuilt || // Is this a non-stackable build?\n // Space missions and religion upgrades (before transcendence is unlocked)\n // are example of non-stackable builds.\n "noStackable" in buildMetaData && buildMetaData.noStackable && buildsPossible + buildMetaData.val >= 1 || // Is this the resource retrieval build? This one is limited to 100 units.\n buildCacheItem.id === "ressourceRetrieval" && buildsPossible + buildMetaData.val >= 100 || buildCacheItem.id === "cryochambers" && this._host.game.bld.getBuildingExt("chronosphere").meta.val <= buildsPossible + buildMetaData.val) {\n for (let priceIndex2 = 0; priceIndex2 < priceIndex; priceIndex2++) {\n if (source === "Space" && prices[priceIndex2].name === "oil") {\n const oilReductionRatio = this._host.game.getEffect("oilReductionRatio");\n const oilPriceRefund = prices[priceIndex2].val * (1 - this._host.game.getLimitedDR(oilReductionRatio, 0.75));\n tempPool.oil += oilPriceRefund * 1.05 ** (buildsPossible + buildMetaData.val);\n } else if (buildCacheItem.id === "cryochambers" && prices[priceIndex2].name === "karma") {\n const burnedParagonRatio = this._host.game.prestige.getBurnedParagonRatio();\n const karmaPriceRefund = prices[priceIndex2].val * (1 - this._host.game.getLimitedDR(0.01 * burnedParagonRatio, 1));\n tempPool.karma += karmaPriceRefund * priceRatio ** (buildsPossible + buildMetaData.val);\n } else {\n const refundVal = prices[priceIndex2].val * priceRatio ** (buildsPossible + buildMetaData.val);\n tempPool[prices[priceIndex2].name] += prices[priceIndex2].name === "void" ? Math.ceil(refundVal) : refundVal;\n }\n }\n if (buildCacheItem.limit && buildCacheItem.limit !== -1) {\n buildsPossible = Math.max(\n 0,\n Math.min(buildsPossible, buildCacheItem.limit - buildCacheItem.val)\n );\n }\n return { count: buildsPossible, remainingResources: tempPool };\n }\n if (spaceOil) {\n tempPool.oil -= oilPrice * 1.05 ** (buildsPossible + buildMetaData.val);\n } else if (cryoKarma) {\n tempPool.karma -= karmaPrice * priceRatio ** (buildsPossible + buildMetaData.val);\n } else {\n const newPriceValue = prices[priceIndex].val * priceRatio ** (buildsPossible + buildMetaData.val);\n tempPool[prices[priceIndex].name] -= prices[priceIndex].name === "void" ? Math.ceil(newPriceValue) : newPriceValue;\n }\n }\n ++buildsPossible;\n }\n return { count: buildsPossible, remainingResources: tempPool };\n }\n /**\n * Try to trigger the build for a given button.\n *\n * @param model The model associated with the button.\n * @param button The build button.\n * @param amount How many items to build.\n * @returns How many items were built.\n */\n construct(model, controller, amount) {\n if ("name" in model === false) {\n return 0;\n }\n if ("controller" in model.options === false) {\n return 0;\n }\n if ("getMetadata" in model.options.controller === false) {\n return 0;\n }\n const meta = model.metadata;\n let counter = 0;\n let amountCalculated = amount;\n const vsMeta = meta;\n if (!isNil(vsMeta.limitBuild) && vsMeta.limitBuild - vsMeta.val < amountCalculated) {\n amountCalculated = vsMeta.limitBuild - vsMeta.val;\n }\n if (model.enabled && controller.hasResources(model) || this._host.game.devMode) {\n while (controller.hasResources(model) && amountCalculated > 0) {\n model.prices = controller.getPrices(model);\n controller.payPrice(model);\n controller.incrementValue(model);\n counter++;\n amountCalculated--;\n }\n if (vsMeta.breakIronWill) {\n this._host.game.ironWill = false;\n }\n if (!isNil(meta)) {\n if ("unlocks" in meta && !isNil(meta.unlocks)) {\n this._host.game.unlock(meta.unlocks);\n }\n if ("upgrades" in meta && !isNil(meta.upgrades)) {\n this._host.game.upgrade(meta.upgrades);\n }\n }\n }\n return counter;\n }\n _isStagedBuild(data) {\n return "stage" in data && "stages" in data && !isNil(data.stage) && !isNil(data.stages);\n }\n /**\n * Determine the price modifier for the given building.\n *\n * @param data The building metadata.\n * @param source The tab the building belongs to.\n * @returns The price modifier for this building.\n * @see `getPriceRatioWithAccessor`@`buildings.js`\n */\n getPriceRatio(data, source) {\n const ratio = (\n // TODO: This seems weird. Why not take the price ratio of the stage as the default?\n this._isStagedBuild(data) ? data.priceRatio || data.stages[data.stage].priceRatio : data.priceRatio ?? 0\n );\n let ratioDiff = 0;\n if (source && source === "Bonfire") {\n ratioDiff = this._host.game.getEffect(`${data.name}PriceRatio`) + this._host.game.getEffect("priceRatio") + this._host.game.getEffect("mapPriceReduction");\n ratioDiff = this._host.game.getLimitedDR(ratioDiff, ratio - 1);\n }\n return ratio + ratioDiff;\n }\n /**\n * Check if a given build could be performed.\n *\n * @param build The build that should be checked.\n * @param build.name The name of the build.\n * @param build.val Probably how many items should be built in total.\n * TODO: Why is this relevant if we only care about a single build being possible?\n * @param prices The current prices for the build.\n * @param priceRatio The global price ratio modifier.\n * @param source What tab did the build originate from?\n * @returns `true` if the build is possible; `false` otherwise.\n */\n singleBuildPossible(build, prices, priceRatio, source) {\n const pricesDiscount = this._host.game.getLimitedDR(\n this._host.game.getEffect(`${build.name}CostReduction`),\n 1\n );\n const priceModifier = 1 - pricesDiscount;\n for (const price of prices) {\n const resourcePriceDiscount = this._host.game.getLimitedDR(\n this._host.game.getEffect(`${price.name}CostReduction`),\n 1\n );\n const resourcePriceModifier = 1 - resourcePriceDiscount;\n const finalResourcePrice = price.val * priceModifier * resourcePriceModifier;\n if (source && source === "Space" && price.name === "oil") {\n const oilModifier = this._host.game.getLimitedDR(\n this._host.game.getEffect("oilReductionRatio"),\n 0.75\n );\n const oilPrice = finalResourcePrice * (1 - oilModifier);\n if (this._workshopManager.getValueAvailable("oil") < oilPrice * 1.05 ** build.val) {\n return false;\n }\n } else if (build.name === "cryochambers" && price.name === "karma") {\n const karmaModifier = this._host.game.getLimitedDR(\n 0.01 * this._host.game.prestige.getBurnedParagonRatio(),\n 1\n );\n const karmaPrice = finalResourcePrice * (1 - karmaModifier);\n if (this._workshopManager.getValueAvailable("karma") < karmaPrice * priceRatio ** build.val) {\n return false;\n }\n } else {\n if (this._workshopManager.getValueAvailable(price.name) < finalResourcePrice * priceRatio ** build.val) {\n return false;\n }\n }\n }\n return true;\n }\n }\n const Buildings = [\n "academy",\n "accelerator",\n "aiCore",\n "amphitheatre",\n "aqueduct",\n "barn",\n "biolab",\n "brewery",\n "calciner",\n "chapel",\n "chronosphere",\n "factory",\n "field",\n "harbor",\n "hut",\n "library",\n "logHouse",\n "lumberMill",\n "magneto",\n "mansion",\n "mine",\n "mint",\n "observatory",\n "oilWell",\n "pasture",\n "quarry",\n "reactor",\n "smelter",\n "steamworks",\n "temple",\n "tradepost",\n "unicornPasture",\n "warehouse",\n "workshop",\n "zebraForge",\n "zebraOutpost",\n "zebraWorkshop",\n "ziggurat"\n ];\n const StagedBuildings = [\n "broadcasttower",\n "dataCenter",\n "hydroplant",\n "solarfarm",\n "spaceport"\n ];\n const Seasons = ["autumn", "spring", "summer", "winter"];\n const Cycles = [\n "charon",\n "umbra",\n "yarn",\n "helios",\n "cath",\n "redmoon",\n "dune",\n "piscine",\n "terminus",\n "kairo"\n ];\n const ResourcesCraftable = [\n "alloy",\n "beam",\n "bloodstone",\n "blueprint",\n "compedium",\n "concrate",\n "eludium",\n "gear",\n "kerosene",\n "manuscript",\n "megalith",\n "parchment",\n "plate",\n "scaffold",\n "ship",\n "slab",\n "steel",\n "tanker",\n "tMythril",\n "thorium",\n "wood"\n ];\n const Resources = [\n ...ResourcesCraftable,\n "alicorn",\n "antimatter",\n "blackcoin",\n "burnedParagon",\n "catnip",\n "coal",\n "culture",\n "elderBox",\n "faith",\n "furs",\n "gflops",\n "gold",\n "hashrates",\n "iron",\n "ivory",\n "karma",\n "kittens",\n "manpower",\n "minerals",\n "necrocorn",\n "oil",\n "paragon",\n "relic",\n "science",\n "sorrow",\n "spice",\n "starchart",\n "tears",\n "temporalFlux",\n "timeCrystal",\n "titanium",\n "unicorns",\n "unobtainium",\n "uranium",\n "void",\n "wrappingPaper",\n "zebras"\n ];\n const Jobs = [\n "any",\n "engineer",\n "farmer",\n "geologist",\n "hunter",\n "miner",\n "priest",\n "scholar",\n "woodcutter"\n ];\n const Traits = [\n "chemist",\n "engineer",\n "manager",\n "metallurgist",\n "merchant",\n "none",\n "scientist",\n "wise"\n ];\n var UnicornItemVariant = /* @__PURE__ */ ((UnicornItemVariant2) => {\n UnicornItemVariant2["Cryptotheology"] = "c";\n UnicornItemVariant2["OrderOfTheSun"] = "s";\n UnicornItemVariant2["Ziggurat"] = "z";\n UnicornItemVariant2["UnicornPasture"] = "zp";\n return UnicornItemVariant2;\n })(UnicornItemVariant || {});\n const ReligionUpgrades = [\n "apocripha",\n "basilica",\n "goldenSpire",\n "scholasticism",\n "solarRevolution",\n "solarchant",\n "stainedGlass",\n "sunAltar",\n "templars",\n "transcendence"\n ];\n const TranscendenceUpgrades = [\n "blackCore",\n "blackLibrary",\n "blackNexus",\n "blackObelisk",\n "blackRadiance",\n "blazar",\n "darkNova",\n "holyGenocide",\n "mausoleum",\n "singularity"\n ];\n const ZigguratUpgrades = [\n "blackPyramid",\n "ivoryCitadel",\n "ivoryTower",\n "marker",\n "skyPalace",\n "sunspire",\n "unicornGraveyard",\n "unicornNecropolis",\n "unicornTomb",\n "unicornUtopia"\n ];\n const Races = [\n "dragons",\n "griffins",\n "nagas",\n "leviathans",\n "lizards",\n "sharks",\n "spiders",\n "zebras"\n ];\n const Policies = [\n "authocracy",\n "bigStickPolicy",\n "carnivale",\n "cityOnAHill",\n "clearCutting",\n "communism",\n "conservation",\n "cryochamberExtraction",\n "culturalExchange",\n "diplomacy",\n "dragonRelationsAstrologers",\n "dragonRelationsDynamicists",\n "dragonRelationsPhysicists",\n "environmentalism",\n "epicurianism",\n "expansionism",\n "extravagance",\n "fascism",\n "frugality",\n "fullIndustrialization",\n "griffinRelationsMachinists",\n "griffinRelationsMetallurgists",\n "griffinRelationsScouts",\n "isolationism",\n "knowledgeSharing",\n "liberalism",\n "liberty",\n "lizardRelationsDiplomats",\n "lizardRelationsEcologists",\n "lizardRelationsPriests",\n "militarizeSpace",\n "monarchy",\n "mysticism",\n "nagaRelationsArchitects",\n "nagaRelationsCultists",\n "nagaRelationsMasons",\n "necrocracy",\n "openWoodlands",\n "outerSpaceTreaty",\n "radicalXenophobia",\n "rationality",\n "rationing",\n "republic",\n "scientificCommunism",\n "sharkRelationsBotanists",\n "sharkRelationsMerchants",\n "sharkRelationsScribes",\n "siphoning",\n "socialism",\n "spiderRelationsChemists",\n "spiderRelationsGeologists",\n "spiderRelationsPaleontologists",\n "stoicism",\n "stripMining",\n "sustainability",\n "technocracy",\n "terraformingInsight",\n "theocracy",\n "tradition",\n "transkittenism",\n "zebraRelationsAppeasement",\n "zebraRelationsBellicosity"\n ];\n const TechnologiesIgnored = ["brewery"];\n const Technologies = [\n "acoustics",\n "advExogeology",\n "agriculture",\n "ai",\n "animal",\n "antimatter",\n "archeology",\n "archery",\n "architecture",\n "artificialGravity",\n "astronomy",\n "biochemistry",\n "biology",\n "blackchain",\n "calendar",\n "chemistry",\n "chronophysics",\n "civil",\n "combustion",\n "construction",\n "cryptotheology",\n "currency",\n "dimensionalPhysics",\n "drama",\n "ecology",\n "electricity",\n "electronics",\n "engineering",\n "exogeology",\n "exogeophysics",\n "genetics",\n "hydroponics",\n "industrialization",\n "machinery",\n "math",\n "mechanization",\n "metal",\n "metalurgy",\n "metaphysics",\n "mining",\n "nanotechnology",\n "navigation",\n "nuclearFission",\n "oilProcessing",\n "orbitalEngineering",\n "paradoxalKnowledge",\n "particlePhysics",\n "philosophy",\n "physics",\n "quantumCryptography",\n "robotics",\n "rocketry",\n "sattelites",\n "steel",\n "superconductors",\n "tachyonTheory",\n "terraformation",\n "theology",\n "thorium",\n "voidSpace",\n "writing"\n ];\n const Missions = [\n "centaurusSystemMission",\n "charonMission",\n "duneMission",\n "furthestRingMission",\n "heliosMission",\n "kairoMission",\n "moonMission",\n "orbitalLaunch",\n "piscineMission",\n "rorschachMission",\n "terminusMission",\n "umbraMission",\n "yarnMission"\n ];\n const SpaceBuildings = [\n "containmentChamber",\n "cryostation",\n "entangler",\n "heatsink",\n "hrHarvester",\n "hydrofracturer",\n "hydroponics",\n "moltenCore",\n "moonBase",\n "moonOutpost",\n "orbitalArray",\n "planetCracker",\n "researchVessel",\n "sattelite",\n "spaceBeacon",\n "spaceElevator",\n "spaceStation",\n "spiceRefinery",\n "sunforge",\n "sunlifter",\n "tectonic",\n "terraformingStation"\n ];\n const ChronoForgeUpgrades = [\n "blastFurnace",\n "ressourceRetrieval",\n "temporalAccelerator",\n "temporalBattery",\n "temporalImpedance",\n "temporalPress",\n "timeBoiler"\n ];\n const VoidSpaceUpgrades = [\n "cryochambers",\n "usedCryochambers",\n "voidHoover",\n "voidRift",\n "chronocontrol",\n "voidResonator"\n ];\n const Upgrades = [\n "advancedAutomation",\n "advancedRefinement",\n "aiBases",\n "aiEngineers",\n "alloyArmor",\n "alloyAxe",\n "alloyBarns",\n "alloySaw",\n "alloyWarehouses",\n "amBases",\n "amDrive",\n "amFission",\n "amReactors",\n "amReactorsMK2",\n "assistance",\n "astrolabe",\n "astrophysicists",\n "augumentation",\n "automatedPlants",\n "barges",\n "biofuel",\n "bolas",\n "cadSystems",\n "caravanserai",\n "carbonSequestration",\n "cargoShips",\n "celestialMechanics",\n "chronoEngineers",\n "chronoforge",\n "coalFurnace",\n "coldFusion",\n "combustionEngine",\n "compositeBow",\n "concreteBarns",\n "concreteHuts",\n "concreteWarehouses",\n "crossbow",\n "cryocomputing",\n "darkEnergy",\n "deepMining",\n "distorsion",\n "electrolyticSmelting",\n "eludiumCracker",\n "eludiumHuts",\n "eludiumReflectors",\n "energyRifts",\n "enrichedThorium",\n "enrichedUranium",\n "factoryAutomation",\n "factoryLogistics",\n "factoryOptimization",\n "factoryProcessing",\n "factoryRobotics",\n "fluidizedReactors",\n "fluxCondensator",\n "fuelInjectors",\n "geodesy",\n "gmo",\n "goldOre",\n "hubbleTelescope",\n "huntingArmor",\n "hydroPlantTurbines",\n "internet",\n "invisibleBlackHand",\n "ironAxes",\n "ironHoes",\n "ironwood",\n "lhc",\n "logistics",\n "longRangeSpaceships",\n "machineLearning",\n "mineralAxes",\n "mineralHoes",\n "miningDrill",\n "mWReactor",\n "nanosuits",\n "neuralNetworks",\n "nuclearPlants",\n "nuclearSmelters",\n "offsetPress",\n "oilDistillation",\n "oilRefinery",\n "orbitalGeodesy",\n "oxidation",\n "photolithography",\n "photovoltaic",\n "pneumaticPress",\n "printingPress",\n "pumpjack",\n "pyrolysis",\n "qdot",\n "railgun",\n "reactorVessel",\n "refrigeration",\n "register",\n "reinforcedBarns",\n "reinforcedSaw",\n "reinforcedWarehouses",\n "relicStation",\n "rotaryKiln",\n "satelliteRadio",\n "satnav",\n "seti",\n "silos",\n "solarSatellites",\n "spaceEngineers",\n "spaceManufacturing",\n "spiceNavigation",\n "starlink",\n "stasisChambers",\n "steelArmor",\n "steelAxe",\n "steelPlants",\n "steelSaw",\n "stoneBarns",\n "storageBunkers",\n "strenghtenBuild",\n "tachyonAccelerators",\n "thinFilm",\n "thoriumEngine",\n "thoriumReactors",\n "titaniumAxe",\n "titaniumBarns",\n "titaniumMirrors",\n "titaniumSaw",\n "titaniumWarehouses",\n "turnSmoothly",\n "unicornSelection",\n "unobtainiumAxe",\n "unobtainiumDrill",\n "unobtainiumHuts",\n "unobtainiumReflectors",\n "unobtainiumSaw",\n "uplink",\n "voidAspiration",\n "voidEnergy",\n "voidReactors"\n ];\n var TimeItemVariant = /* @__PURE__ */ ((TimeItemVariant2) => {\n TimeItemVariant2["Chronoforge"] = "chrono";\n TimeItemVariant2["VoidSpace"] = "void";\n return TimeItemVariant2;\n })(TimeItemVariant || {});\n const UnicornItems = [\n "ivoryCitadel",\n "ivoryTower",\n "skyPalace",\n "sunspire",\n "unicornPasture",\n "unicornTomb",\n "unicornUtopia"\n ];\n const ReligionOptions = [\n "sacrificeUnicorns",\n "sacrificeAlicorns",\n "refineTears",\n "refineTimeCrystals",\n "transcend",\n "adore",\n "autoPraise"\n ];\n class Setting {\n constructor(enabled = false) {\n __publicField(this, "enabled");\n this.enabled = enabled;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n this.enabled = setting2.enabled ?? this.enabled;\n }\n serialize() {\n return this;\n }\n }\n class SettingLimited extends Setting {\n constructor(enabled = false, limited = false) {\n super(enabled);\n __publicField(this, "limited");\n this.limited = limited;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.limited = setting2.limited ?? this.limited;\n }\n }\n class SettingTrigger extends Setting {\n constructor(enabled = false, trigger = -1) {\n super(enabled);\n __publicField(this, "trigger");\n this.trigger = trigger;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.trigger = setting2.trigger ?? this.trigger;\n }\n }\n class SettingThreshold extends Setting {\n constructor(enabled = false, threshold = 1) {\n super(enabled);\n __publicField(this, "trigger");\n this.trigger = threshold;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.trigger = setting2.trigger ?? this.trigger;\n }\n }\n class SettingMax extends Setting {\n constructor(enabled = false, max = 0) {\n super(enabled);\n __publicField(this, "max");\n this.max = max;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.max = setting2.max ?? this.max;\n }\n }\n class SettingLimitedMax extends SettingLimited {\n constructor(enabled = false, limited = false, max = 0) {\n super(enabled, limited);\n __publicField(this, "max");\n this.max = max;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.max = setting2.max ?? this.max;\n }\n }\n class SettingLimitedMaxTrigger extends SettingLimitedMax {\n constructor(enabled = false, limited = false, max = 0, trigger = -1) {\n super(enabled, limited, max);\n __publicField(this, "trigger");\n this.trigger = trigger;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.trigger = setting2.trigger ?? this.trigger;\n }\n }\n class SettingLimitedTrigger extends SettingLimited {\n constructor(enabled = false, limited = false, trigger = -1) {\n super(enabled, limited);\n __publicField(this, "trigger");\n this.trigger = trigger;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.trigger = setting2.trigger ?? this.trigger;\n }\n }\n class SettingTriggerMax extends SettingTrigger {\n constructor(enabled = false, trigger = -1, max = 0) {\n super(enabled, trigger);\n __publicField(this, "max");\n this.max = max;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.max = setting2.max ?? this.max;\n }\n }\n class SettingThresholdMax extends SettingThreshold {\n constructor(enabled = false, trigger = 1, max = 0) {\n super(enabled, trigger);\n __publicField(this, "max");\n this.max = max;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.max = setting2.max ?? this.max;\n }\n }\n class SettingOptions {\n constructor(selected, options = new Array()) {\n __privateAdd(this, _options);\n __publicField(this, "selected");\n if (isNil(options.find((option) => option.value === selected))) {\n throw new Error("Provided selected value is not in provided options.");\n }\n this.selected = selected;\n __privateSet(this, _options, options);\n }\n get options() {\n return __privateGet(this, _options);\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n this.selected = setting2.selected ?? this.selected;\n }\n }\n _options = new WeakMap();\n class SettingBuySellThreshold extends SettingThreshold {\n constructor(enabled = false, buy = 950, sell = 1e3, trigger = 1) {\n super(enabled, trigger);\n __publicField(this, "buy");\n __publicField(this, "sell");\n this.buy = buy;\n this.sell = sell;\n }\n load(setting2) {\n if (isNil(setting2)) {\n return;\n }\n super.load(setting2);\n this.buy = setting2.buy ?? this.buy;\n this.sell = setting2.sell ?? this.sell;\n }\n }\n class BuildingUpgradeSetting extends Setting {\n constructor(upgrade, enabled = false) {\n super(enabled);\n __privateAdd(this, _upgrade);\n __privateSet(this, _upgrade, upgrade);\n }\n get upgrade() {\n return __privateGet(this, _upgrade);\n }\n }\n _upgrade = new WeakMap();\n class BuildingUpgradeSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "buildings");\n this.buildings = this.initBuildings();\n }\n initBuildings() {\n const items = {};\n for (const item of StagedBuildings) {\n items[item] = new BuildingUpgradeSetting(item);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n });\n }\n }\n class BonfireBuildingSetting extends SettingTriggerMax {\n constructor(building, enabled = false, trigger = -1, max = 0, baseStage) {\n super(enabled, trigger, max);\n /**\n * In case this is an upgrade of another building, this is the name of the\n * base building.\n */\n __privateAdd(this, _baseBuilding);\n __privateAdd(this, _building);\n /**\n * In case this is an upgradable building, this indicates the level of\n * the stage.\n */\n __privateAdd(this, _stage, 0);\n __privateSet(this, _building, building);\n if (baseStage) {\n __privateSet(this, _stage, 1);\n __privateSet(this, _baseBuilding, baseStage);\n }\n }\n get baseBuilding() {\n return __privateGet(this, _baseBuilding);\n }\n get building() {\n return __privateGet(this, _building);\n }\n get stage() {\n return __privateGet(this, _stage);\n }\n }\n _baseBuilding = new WeakMap();\n _building = new WeakMap();\n _stage = new WeakMap();\n class BonfireSettings extends SettingTrigger {\n constructor(enabled = false, trigger = -1, gatherCatnip = new Setting(), turnOnSteamworks = new Setting(), turnOnMagnetos = new Setting(), turnOnReactors = new Setting(), upgradeBuildings = new BuildingUpgradeSettings()) {\n super(enabled, trigger);\n __publicField(this, "buildings");\n __publicField(this, "gatherCatnip");\n __publicField(this, "turnOnMagnetos");\n __publicField(this, "turnOnSteamworks");\n __publicField(this, "turnOnReactors");\n __publicField(this, "upgradeBuildings");\n this.buildings = this.initBuildings();\n this.gatherCatnip = gatherCatnip;\n this.turnOnSteamworks = turnOnSteamworks;\n this.turnOnMagnetos = turnOnMagnetos;\n this.turnOnReactors = turnOnReactors;\n this.upgradeBuildings = upgradeBuildings;\n }\n initBuildings() {\n const baseStage = {\n broadcasttower: "amphitheatre",\n dataCenter: "library",\n hydroplant: "aqueduct",\n solarfarm: "pasture",\n spaceport: "warehouse"\n };\n const items = {};\n for (const item of Buildings) {\n if (item === "unicornPasture") {\n continue;\n }\n items[item] = new BonfireBuildingSetting(item);\n }\n for (const item of StagedBuildings) {\n items[item] = new BonfireBuildingSetting(item, false, -1, 0, baseStage[item]);\n }\n return items;\n }\n load(settings) {\n var _a, _b, _c, _d;\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n building.max = (item == null ? void 0 : item.max) ?? building.max;\n building.trigger = (item == null ? void 0 : item.trigger) ?? building.trigger;\n });\n this.gatherCatnip.enabled = ((_a = settings.gatherCatnip) == null ? void 0 : _a.enabled) ?? this.gatherCatnip.enabled;\n this.turnOnSteamworks.enabled = ((_b = settings.turnOnSteamworks) == null ? void 0 : _b.enabled) ?? this.turnOnSteamworks.enabled;\n this.turnOnMagnetos.enabled = ((_c = settings.turnOnMagnetos) == null ? void 0 : _c.enabled) ?? this.turnOnMagnetos.enabled;\n this.turnOnReactors.enabled = ((_d = settings.turnOnReactors) == null ? void 0 : _d.enabled) ?? this.turnOnReactors.enabled;\n this.upgradeBuildings.load(settings.upgradeBuildings);\n }\n }\n class TabManager {\n constructor(host, name) {\n __publicField(this, "_host");\n __publicField(this, "tab");\n this._host = host;\n const tab = this._host.game.tabs.find((subject) => subject.tabId === name);\n if (isNil(tab)) {\n throw new Error(`Unable to find tab ${name}`);\n }\n this.tab = tab;\n this.render();\n }\n render() {\n if (this._host.game.ui.activeTabId !== this.tab.tabId) {\n this.tab.render();\n }\n return this;\n }\n }\n class BonfireManager {\n constructor(host, workshopManager, settings = new BonfireSettings()) {\n __publicField(this, "_host");\n __publicField(this, "settings");\n __publicField(this, "manager");\n __publicField(this, "_bulkManager");\n __publicField(this, "_workshopManager");\n this._host = host;\n this.settings = settings;\n this.manager = new TabManager(this._host, "Bonfire");\n this._workshopManager = workshopManager;\n this._bulkManager = new BulkPurchaseHelper(this._host, this._workshopManager);\n }\n tick(context) {\n if (!this.settings.enabled) {\n return;\n }\n this.manager.render();\n this.autoBuild(context);\n this.autoMisc(context);\n }\n /**\n * Try to build as many of the passed buildings as possible.\n * Usually, this is called at each iteration of the automation engine to\n * handle the building of items on the Bonfire tab.\n *\n * @param builds The buildings to build.\n */\n autoBuild(context, builds = this.settings.buildings) {\n const bulkManager = this._bulkManager;\n const metaData = {};\n for (const build of Object.values(builds)) {\n metaData[build.building] = this.getBuild(\n build.baseBuilding ?? build.building\n ).meta;\n }\n const sectionTrigger = this.settings.trigger;\n const buildList = bulkManager.bulk(builds, metaData, sectionTrigger, "Bonfire");\n for (const build of buildList.filter((item) => 0 < item.count)) {\n this.build(build.name || build.id, build.stage, build.count);\n context.requestGameUiRefresh = true;\n }\n }\n autoUpgrade(context) {\n var _a, _b, _c, _d, _e, _f, _g;\n const pastures = this._host.game.bld.getBuildingExt("pasture").meta.stage === 0 ? this._host.game.bld.getBuildingExt("pasture").meta.val : 0;\n const aqueducts = this._host.game.bld.getBuildingExt("aqueduct").meta.stage === 0 ? this._host.game.bld.getBuildingExt("aqueduct").meta.val : 0;\n const pastureMeta = this._host.game.bld.getBuildingExt("pasture").meta;\n if (this.settings.upgradeBuildings.buildings.solarfarm.enabled && pastureMeta.unlocked && pastureMeta.stage === 0 && mustExist(pastureMeta.stages)[1].stageUnlocked) {\n if (this._workshopManager.getPotentialCatnip(true, 0, aqueducts) > 0) {\n const prices = mustExist(pastureMeta.stages)[1].prices;\n if (this._bulkManager.singleBuildPossible(pastureMeta, prices, 1)) {\n const button2 = this.getBuildButton("pasture", 0);\n if (!isNil(button2 == null ? void 0 : button2.model)) {\n button2.controller.sellInternal(button2.model, 0, false);\n pastureMeta.on = 0;\n pastureMeta.val = 0;\n pastureMeta.stage = 1;\n this._host.engine.iactivity("upgrade.building.pasture", [], "ks-upgrade");\n (_a = this._host.game.ui) == null ? void 0 : _a.render();\n this.build("pasture", 1, 1);\n context.requestGameUiRefresh = true;\n }\n }\n }\n }\n const aqueductMeta = this._host.game.bld.getBuildingExt("aqueduct").meta;\n if (this.settings.upgradeBuildings.buildings.hydroplant.enabled && aqueductMeta.unlocked && aqueductMeta.stage === 0 && mustExist(aqueductMeta.stages)[1].stageUnlocked) {\n if (this._workshopManager.getPotentialCatnip(true, pastures, 0) > 0) {\n const prices = mustExist(aqueductMeta.stages)[1].prices;\n if (this._bulkManager.singleBuildPossible(aqueductMeta, prices, 1)) {\n const button2 = this.getBuildButton("aqueduct", 0);\n if (!isNil(button2 == null ? void 0 : button2.model)) {\n button2.controller.sellInternal(button2.model, 0, false);\n aqueductMeta.on = 0;\n aqueductMeta.val = 0;\n aqueductMeta.stage = 1;\n (_b = aqueductMeta.calculateEffects) == null ? void 0 : _b.call(aqueductMeta, aqueductMeta, this._host.game);\n this._host.engine.iactivity("upgrade.building.aqueduct", [], "ks-upgrade");\n (_c = this._host.game.ui) == null ? void 0 : _c.render();\n this.build("aqueduct", 1, 1);\n context.requestGameUiRefresh = true;\n }\n }\n }\n }\n const libraryMeta = this._host.game.bld.getBuildingExt("library").meta;\n if (this.settings.upgradeBuildings.buildings.dataCenter.enabled && libraryMeta.unlocked && libraryMeta.stage === 0 && mustExist(libraryMeta.stages)[1].stageUnlocked) {\n let energyConsumptionRate = this._host.game.workshop.get("cryocomputing").researched ? 1 : 2;\n if (this._host.game.challenges.currentChallenge === "energy") {\n energyConsumptionRate *= 2;\n }\n let libToDat = 3;\n if (this._host.game.workshop.get("uplink").researched) {\n libToDat *= 1 + this._host.game.bld.getBuildingExt("biolab").meta.val * this._host.game.getEffect("uplinkDCRatio");\n }\n if (this._host.game.workshop.get("machineLearning").researched) {\n libToDat *= 1 + this._host.game.bld.getBuildingExt("aiCore").meta.on * this._host.game.getEffect("dataCenterAIRatio");\n }\n if (this._host.game.resPool.energyProd >= this._host.game.resPool.energyCons + energyConsumptionRate * libraryMeta.val / libToDat) {\n const prices = mustExist(libraryMeta.stages)[1].prices;\n if (this._bulkManager.singleBuildPossible(libraryMeta, prices, 1)) {\n const button2 = mustExist(this.getBuildButton("library", 0));\n if (isNil(button2.model)) {\n return;\n }\n button2.controller.sellInternal(button2.model, 0, false);\n libraryMeta.on = 0;\n libraryMeta.val = 0;\n libraryMeta.stage = 1;\n (_d = libraryMeta.calculateEffects) == null ? void 0 : _d.call(libraryMeta, libraryMeta, this._host.game);\n this._host.engine.iactivity("upgrade.building.library", [], "ks-upgrade");\n (_e = this._host.game.ui) == null ? void 0 : _e.render();\n this.build("library", 1, 1);\n context.requestGameUiRefresh = true;\n return;\n }\n }\n }\n const warehouseMeta = this._host.game.bld.getBuildingExt("warehouse").meta;\n if (this.settings.upgradeBuildings.buildings.spaceport.enabled && warehouseMeta.unlocked && warehouseMeta.stage === 0 && mustExist(warehouseMeta.stages)[1].stageUnlocked) {\n const prices = mustExist(warehouseMeta.stages)[1].prices;\n if (this._bulkManager.singleBuildPossible(warehouseMeta, prices, 1)) {\n const button2 = this.getBuildButton("warehouse", 0);\n if (!isNil(button2 == null ? void 0 : button2.model)) {\n button2.controller.sellInternal(button2.model, 0, false);\n warehouseMeta.on = 0;\n warehouseMeta.val = 0;\n warehouseMeta.stage = 1;\n this._host.engine.iactivity("upgrade.building.warehouse", [], "ks-upgrade");\n (_f = this._host.game.ui) == null ? void 0 : _f.render();\n this.build("warehouse", 1, 1);\n context.requestGameUiRefresh = true;\n return;\n }\n }\n }\n const amphitheatreMeta = this._host.game.bld.getBuildingExt("amphitheatre").meta;\n if (this.settings.upgradeBuildings.buildings.broadcasttower.enabled && amphitheatreMeta.unlocked && amphitheatreMeta.stage === 0 && mustExist(amphitheatreMeta.stages)[1].stageUnlocked) {\n const prices = mustExist(amphitheatreMeta.stages)[1].prices;\n if (this._bulkManager.singleBuildPossible(amphitheatreMeta, prices, 1)) {\n const button2 = this.getBuildButton("amphitheatre", 0);\n if (!isNil(button2 == null ? void 0 : button2.model)) {\n button2.controller.sellInternal(button2.model, 0, false);\n amphitheatreMeta.on = 0;\n amphitheatreMeta.val = 0;\n amphitheatreMeta.stage = 1;\n this._host.engine.iactivity("upgrade.building.amphitheatre", [], "ks-upgrade");\n (_g = this._host.game.ui) == null ? void 0 : _g.render();\n this.build("amphitheatre", 1, 1);\n context.requestGameUiRefresh = true;\n }\n }\n }\n }\n autoMisc(context) {\n if (this.settings.turnOnSteamworks.enabled) {\n const steamworks = this._host.game.bld.getBuildingExt("steamworks");\n if (steamworks.meta.val && steamworks.meta.on === 0) {\n const button2 = mustExist(this.getBuildButton("steamworks"));\n if (isNil(button2.model)) {\n return;\n }\n button2.controller.onAll(button2.model);\n }\n }\n if (this.settings.turnOnMagnetos.enabled) {\n const magnetos = this._host.game.bld.getBuildingExt("magneto");\n if (magnetos.meta.val && magnetos.meta.on < magnetos.meta.val) {\n const button2 = mustExist(this.getBuildButton("magneto"));\n if (isNil(button2.model)) {\n return;\n }\n button2.controller.onAll(button2.model);\n }\n }\n if (this.settings.turnOnReactors.enabled) {\n const reactors = this._host.game.bld.getBuildingExt("reactor");\n if (reactors.meta.val && reactors.meta.on < reactors.meta.val) {\n const button2 = mustExist(this.getBuildButton("reactor"));\n if (isNil(button2.model)) {\n return;\n }\n button2.controller.onAll(button2.model);\n }\n }\n if (this.settings.upgradeBuildings.enabled) {\n this.autoUpgrade(context);\n }\n if (this.settings.gatherCatnip.enabled) {\n this.autoGather();\n }\n }\n autoGather() {\n const controller = new classes.game.ui.GatherCatnipButtonController(\n this._host.game\n );\n for (let clicks = 0; clicks < Math.floor(this._host.engine.settings.interval / 20); ++clicks) {\n controller.buyItem(void 0, null);\n }\n }\n build(name, _stage3, amount) {\n let amountCalculated = amount;\n const amountTemp = amountCalculated;\n let label2;\n const itemMetaRaw = game.getUnlockByName(name, "buildings");\n const meta = new classes.BuildingMeta(itemMetaRaw).getMeta();\n if ("stages" in meta) {\n const controller = new classes.ui.btn.StagingBldBtnController(\n this._host.game\n );\n const model = controller.fetchModel({\n building: name,\n controller,\n description: mustExist(meta.description),\n name: mustExist(meta.label),\n twoRow: false\n });\n amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);\n label2 = meta.label ?? "";\n } else {\n const controller = new classes.ui.btn.BuildingBtnModernController(\n this._host.game\n );\n const model = controller.fetchModel({\n building: name,\n controller,\n description: mustExist(meta.description),\n name: mustExist(meta.label),\n twoRow: false\n });\n amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);\n label2 = meta.label ?? "";\n }\n if (amountCalculated !== amountTemp) {\n console.warn(\n ...cl(`${label2} Amount ordered: ${amountTemp} Amount Constructed: ${amountCalculated}`)\n );\n if (amountCalculated === 0) {\n return;\n }\n }\n this._host.engine.storeForSummary(label2, amountCalculated, "build");\n if (amountCalculated === 1) {\n this._host.engine.iactivity("act.build", [label2], "ks-build");\n } else {\n this._host.engine.iactivity(\n "act.builds",\n [label2, this._host.renderAbsolute(amountCalculated)],\n "ks-build"\n );\n }\n }\n _getBuildLabel(meta, stage) {\n return meta.stages && !isNil(stage) ? meta.stages[stage].label : mustExist(meta.label);\n }\n getBuild(name) {\n return this._host.game.bld.getBuildingExt(name);\n }\n getBuildButton(name, stage = 0) {\n const metaRaw = game.bld.get(name);\n const buildingMeta = new classes.BuildingMeta(metaRaw).getMeta();\n const meta = !isNil(buildingMeta.stages) ? buildingMeta.stages[stage] : metaRaw;\n const controller = "stages" in meta ? new classes.ui.btn.StagingBldBtnController(\n this._host.game\n ) : new classes.ui.btn.BuildingBtnModernController(\n this._host.game\n );\n const model = controller.fetchModel({\n building: name,\n description: meta.description,\n key: name,\n name: meta.label\n });\n return { controller, model };\n }\n }\n class ActivitySummary {\n constructor(host) {\n __publicField(this, "_host");\n /**\n * The day at which the activity summary was last reset.\n */\n __publicField(this, "_lastday");\n /**\n * The year at which the activity summary was last reset.\n */\n __publicField(this, "_lastyear");\n /**\n * The individual sections/categories of the activity summary.\n */\n __publicField(this, "_sections", /* @__PURE__ */ new Map());\n this._host = host;\n this.resetActivity();\n }\n resetActivity() {\n this._sections = /* @__PURE__ */ new Map();\n this._lastday = this._host.game.calendar.day;\n this._lastyear = this._host.game.calendar.year;\n }\n storeActivity(name, amount = 1, section = "other") {\n if (!this._sections.has(section)) {\n this._sections.set(section, /* @__PURE__ */ new Map());\n }\n const summarySection = mustExist(this._sections.get(section));\n if (!summarySection.has(name)) {\n summarySection.set(name, 0);\n }\n summarySection.set(name, mustExist(summarySection.get(name)) + amount);\n }\n renderSummary() {\n const summary = new Array();\n if (this._sections.has("other")) {\n const section = mustExist(this._sections.get("other"));\n section.forEach(\n (amount, name) => summary.push(\n this._host.engine.i18n(`summary.${name}`, [\n this._host.game.getDisplayValueExt(amount)\n ])\n )\n );\n }\n if (this._sections.has("research")) {\n const section = mustExist(this._sections.get("research"));\n section.forEach((_amount, name) => {\n summary.push(this._host.engine.i18n("summary.tech", [ucfirst(name)]));\n });\n }\n if (this._sections.has("upgrade")) {\n const section = mustExist(this._sections.get("upgrade"));\n section.forEach((_amount, name) => {\n summary.push(this._host.engine.i18n("summary.upgrade", [ucfirst(name)]));\n });\n }\n if (this._sections.has("build")) {\n const section = mustExist(this._sections.get("build"));\n section.forEach((amount, name) => {\n summary.push(\n this._host.engine.i18n("summary.building", [\n this._host.game.getDisplayValueExt(amount),\n ucfirst(name)\n ])\n );\n });\n }\n if (this._sections.has("refine")) {\n const section = mustExist(this._sections.get("refine"));\n section.forEach((amount, name) => {\n summary.push(\n this._host.engine.i18n("summary.refine", [\n this._host.game.getDisplayValueExt(amount),\n ucfirst(name)\n ])\n );\n });\n }\n if (this._sections.has("faith")) {\n const section = mustExist(this._sections.get("faith"));\n section.forEach((amount, name) => {\n summary.push(\n this._host.engine.i18n("summary.sun", [\n this._host.game.getDisplayValueExt(amount),\n ucfirst(name)\n ])\n );\n });\n }\n if (this._sections.has("craft")) {\n const section = mustExist(this._sections.get("craft"));\n section.forEach((amount, name) => {\n summary.push(\n this._host.engine.i18n("summary.craft", [\n this._host.game.getDisplayValueExt(amount),\n ucfirst(name)\n ])\n );\n });\n }\n if (this._sections.has("trade")) {\n const section = mustExist(this._sections.get("trade"));\n section.forEach((amount, name) => {\n summary.push(\n this._host.engine.i18n("summary.trade", [\n this._host.game.getDisplayValueExt(amount),\n ucfirst(name)\n ])\n );\n });\n }\n if (this._lastday && this._lastyear) {\n let years = this._host.game.calendar.year - this._lastyear;\n let days = this._host.game.calendar.day - this._lastday;\n if (days < 0) {\n years -= 1;\n days += 400;\n }\n let duration = "";\n if (years > 0) {\n duration += `${years} `;\n duration += years === 1 ? this._host.engine.i18n("summary.year") : this._host.engine.i18n("summary.years");\n }\n if (days >= 0) {\n if (years > 0) duration += this._host.engine.i18n("summary.separator");\n duration += `${roundToTwo(days)} `;\n duration += days === 1 ? this._host.engine.i18n("summary.day") : this._host.engine.i18n("summary.days");\n }\n summary.push(this._host.engine.i18n("summary.head", [duration]));\n }\n return summary;\n }\n }\n const copy$3 = "Copy";\n const reset$3 = "Reset";\n const update$3 = "Update";\n const enUS$1 = {\n "act.accelerate": "Accelerate time!",\n "act.adore": "Adore the galaxy! Accumulated {0} worship to {1} epiphany",\n "act.blackcoin.buy": "Kittens sold your Relics and bought {0} Blackcoins",\n "act.blackcoin.sell": "Kittens sold your Blackcoins and bought {0} Relics",\n "act.build": "Kittens have built a new {0}",\n "act.builds": "Kittens have built a new {0} {1} times",\n "act.craft": "Kittens have crafted {0} {1}",\n "act.distribute": "Distributed a kitten to {0}",\n "act.elect": "Kittens have elected a new leader.",\n "act.feed": "Kittens fed the Elders. The elders are pleased",\n "act.fix.cry": "Kittens fixed {0} Cryochambers",\n "act.hunt": "Sent kittens on {0} hunts",\n "act.observe": "Kitten Scientists have observed a star",\n "act.praise": "Praised the sun! Accumulated {0} faith to {1} worship",\n "act.promote": "Kittens\' leader has been promoted to rank {0}",\n "act.refineTCs": "Refined {0} time crystals",\n "act.refineTears": "Refined {0} tears into BLS",\n "act.sacrificeAlicorns": "Sacrificed {0} alicorns",\n "act.sacrificeUnicorns": "Sacrificed {0} unicorns",\n "act.sun.discover": "Kittens have discovered {0}",\n "act.sun.discovers": "Kittens have discovered {0} {1} times",\n "act.time.activeHeatTransferEnd": "End active Heat Transfer",\n "act.time.activeHeatTransferStart": "Start active Heat Transfer",\n "act.time.getTemporalFlux": "Burn crystals to obtain time flux to maintain time acceleration",\n "act.time.skip": "Kittens combust a time crystal, {0} years skipped!",\n "act.trade": "Kittens have traded {0} times with {1}",\n "act.transcend": "Spent {0} epiphany, Transcended to T-level: {1}",\n "blackcoin.buy": "Buy Limit: {0}",\n "blackcoin.buy.prompt": "Enter at which price you want to stop buying blackcoins.",\n "blackcoin.buy.promptExplainer": "Blackcoin price always rises from 800 to 1100 (roughly), then it crashes. You usually want to buy until shortly before you sell.",\n "blackcoin.buy.promptTitle": "Buy Limit for Blackcoins (Current: {0})",\n "blackcoin.buy.title": "Buy Blackcoins until price reaches {0}",\n "blackcoin.buy.trigger": "buying Blackcoins (in relics)",\n "blackcoin.sell": "Sell Order: {0}",\n "blackcoin.sell.prompt": "Enter at which price you want to sell all your blackcoins.",\n "blackcoin.sell.promptExplainer": "Blackcoin price always rises from 800 to 1100 (roughly), then it crashes. You usually want to sell close to the highest possible price.",\n "blackcoin.sell.promptTitle": "Sell Order for Blackcoins (Current: {0})",\n "blackcoin.sell.title": "Sell Blackcoins when price reaches {0}",\n "build.embassies": "Built {0} embassies for {1}",\n "build.embassy": "Built {0} embassy for {1}",\n copy: copy$3,\n "craft.limited": "Crafting {0}: limited to be proportional to cost ratio",\n "craft.unlimited": "Crafting {0}: unlimited",\n "delete": "Delete",\n "dispose.necrocorn": "Kittens disposed of inefficient necrocorns",\n "festival.extend": "Kittens extend the festival",\n "festival.hold": "Kittens begin holding a festival",\n "filter.accelerate": "Tempus Fugit",\n "filter.adore": "Adoring",\n "filter.allKG": "All KG log entries.",\n "filter.build": "Building",\n "filter.craft": "Crafting",\n "filter.disable": "Disabled {0} log messages",\n "filter.distribute": "Distribute",\n "filter.enable": "Enabled {0} log messages",\n "filter.explainer": "Disabled items are hidden from the log.",\n "filter.faith": "Order of the Sun",\n "filter.festival": "Festivals",\n "filter.hunt": "Hunting",\n "filter.misc": "Miscellaneous",\n "filter.praise": "Praising",\n "filter.promote": "Promote leader",\n "filter.research": "Researching",\n "filter.star": "Astronomical Events",\n "filter.timeSkip": "Time Skip",\n "filter.trade": "Trading",\n "filter.transcend": "Transcend",\n "filter.upgrade": "Upgrading",\n "option.accelerate": "Tempus Fugit",\n "option.autofeed": "Feed Leviathans",\n "option.catnip": "Gather Catnip",\n "option.crypto": "Trade Blackcoin",\n "option.elect": "Elect leader",\n "option.elect.job": "Job",\n "option.elect.job.any": "Any",\n "option.elect.trait": "Trait",\n "option.embassies": "Build Embassies",\n "option.faith.adore": "Adore the Galaxy",\n "option.faith.autoPraise": "Praise the Sun",\n "option.faith.best.unicorn": "Automate Build Order",\n "option.faith.refineTears": "Refine Tears",\n "option.faith.refineTimeCrystals": "Refine TCs",\n "option.faith.sacrificeAlicorns": "Sacrifice Alicorns",\n "option.faith.sacrificeUnicorns": "Sacrifice Unicorns",\n "option.faith.transcend": "Transcend",\n "option.festival": "Hold festivals",\n "option.fix.cry": "Fix Cryochamber",\n "option.hunt": "Hunt",\n "option.magnetos": "Turn on Magnetos",\n "option.observe": "Observe Astro Events",\n "option.praise": "Praise the Sun",\n "option.promote": "Promote leader",\n "option.promotekittens": "Promote kittens",\n "option.reactors": "Turn on Reactors",\n "option.shipOverride": "Force Ships to 243",\n "option.steamworks": "Turn on Steamworks",\n "option.time.activeHeatTransfer": "Active Heat Transfer",\n "option.time.reset": "Reset Timeline (Danger!)",\n "option.time.skip": "Time Skip",\n "option.time.skip.ignoreOverheat": "Ignore overheat",\n reset: reset$3,\n "reset.after": "Nice to meet you, the cute Kitten Scientists will serve you",\n "reset.cancel.activity": "Meoston, We Have a Problem",\n "reset.cancel.message": "Timeline Reset canceled",\n "reset.check": "Trigger for {0}: {1}, you have {2}",\n "reset.checked": "All conditions are met, the timeline will restart in the next few seconds!",\n "reset.countdown.0": "0 - Temporal rifts opened!",\n "reset.countdown.1": "1 - Time engine start",\n "reset.countdown.2": "2 - Boosting the chronoforge",\n "reset.countdown.3": "3 - Opening temporal rifts",\n "reset.countdown.4": "4 - Turning off satellite",\n "reset.countdown.5": "5 - Melting blackcoins",\n "reset.countdown.6": "6 - Starting time engines",\n "reset.countdown.7": "7 - Disassembling railguns",\n "reset.countdown.8": "8 - Releasing lizards",\n "reset.countdown.9": "9 - Sacrificing unicorns",\n "reset.countdown.10": "10 - Harvesting catnip",\n "reset.last.message": "See you next poincaré recurrence",\n "reset.tip": \'You can cancel this reset by disabling "Enable Kitten Scientists" at the top of the settings.\',\n "resources.consume": "Consume: {0}",\n "resources.consume.prompt": "Enter how much of the resource you want automations to consume as a percentage between 0.0 and 100.0.",\n "resources.consume.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "resources.consume.promptTitle": "Consumption Share for {0} (Current: {1})",\n "resources.consume.set": "Consume rate for {0}",\n "resources.consume.title": "Consuming {0} of {1}",\n "resources.consume.titleZero": "Not consuming {0}",\n "resources.stock.prompt": "Enter how much of the resource you always want to keep in stock.",\n "resources.stock.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "resources.stock.promptTitle": "Stock value for {0} (Current: {1})",\n "resources.stock.title": "Keeping {0} {1} in stock",\n "resources.stock.titleInfinite": "Keeping all {0} in stock",\n "resources.stock.titleZero": "Not keeping any {0} in stock",\n "state.compress": "Compress copied Kittens Game saves",\n "state.confirmDestruction": "Are you sure?",\n "state.copied.game": "Save \'{0}\' copied to clipboard.",\n "state.copied.gameCurrent": "Current save copied to clipboard.",\n "state.copied.state": "State \'{0}\' copied to clipboard.",\n "state.copied.stateCurrent": "Current state copied to clipboard.",\n "state.copy.game": "Copy this save to the clipboard.",\n "state.copy.gameCurrent": "Copy the entire Kittens Game save (includes KS settings) to the clipboard.",\n "state.copy.state": "Copy these settings to the clipboard.",\n "state.copy.stateCurrent": "Copy the current Kitten Scientists settings to the clipboard.",\n "state.delete.game": "Delete this save.",\n "state.delete.state": "Delete these settings.",\n "state.deleted.game": "Save \'{0}\' deleted.",\n "state.deleted.state": "State \'{0}\' deleted.",\n "state.edit.game": "Change the name of this save.",\n "state.edit.state": "Change the name of these settings.",\n "state.exportAll": "Backup",\n "state.exportAllTitle": "Stores all local states in a single file and downloads it.",\n "state.import": "Import settings/saves",\n "state.imported.game": "Save imported.",\n "state.imported.state": "State imported.",\n "state.importedState": "Imported state {0}",\n "state.importTitle": "Paste a save or settings from your clipboard.\\nContents will be automatically detected and handled accordingly.",\n "state.loaded.game": "Save \'{0}\' loaded.",\n "state.loaded.state": "State \'{0}\' loaded.",\n "state.loadPrompt": "Paste your (un/compressed) save or settings here:",\n "state.local": "Local storage management",\n "state.localGames": "Kittens Game Saves",\n "state.localStates": "Kitten Scientists Settings",\n "state.new": "New",\n "state.noConfirm": "Don\'t ask for confirmation",\n "state.store": "Store",\n "state.stored.game": "Save stored.",\n "state.stored.state": "State stored.",\n "state.storeFactory": "Create a new state from factory defaults.",\n "state.storeGame": "Create a new save from the current game.",\n "state.storeGame.prompt": "Provide a label for this save:",\n "state.storeState": "Create a new state from current settings.",\n "state.storeState.prompt": "Provide a label for this state:",\n "state.title": "State Management",\n "state.unlabeledGame": "unlabeled save",\n "state.unlabeledState": "unlabeled state",\n "state.update.game": "Save the current game into this slot.",\n "state.update.state": "Save the current settings into this slot.",\n "state.updated.game": "Save \'{0}\' updated.",\n "state.updated.state": "State \'{0}\' updated.",\n "status.auto.disable": "Disabled Auto {0}",\n "status.auto.enable": "Enabled Auto {0}",\n "status.ks.disable": "Disabling the Kitten Scientists!",\n "status.ks.enable": "Enabling the Kitten Scientists!",\n "status.ks.init": "Kitten Scientists initialized.",\n "status.ks.upgrade": "Kitten Scientists {0} (ours is {1}) is available at {2}.",\n "status.reset.check.disable": "Disabled check {0} before Reset Timeline",\n "status.reset.check.enable": "Enabled check {0} before Reset Timeline",\n "status.resource.disable": "Disabled {0} resource management",\n "status.resource.enable": "Enabled {0} resource management",\n "status.sub.disable": "Disabled {0}",\n "status.sub.enable": "Enabled {0}",\n "summary.accelerate": "Accelerated time {0} times",\n "summary.adore": "Accumulated {0} epiphany by adoring the galaxy",\n "summary.building": "Built {0} {1}",\n "summary.craft": "Crafted {0} {1}",\n "summary.day": "day",\n "summary.days": "days",\n "summary.distribute": "Helped {0} kittens find a job",\n "summary.embassy": "Built {0} embassies",\n "summary.feed": "Fed the elders {0} necrocorns",\n "summary.festival": "Held {0} festivals",\n "summary.fix.cry": "Fixed {0} cryochambers",\n "summary.head": "Summary of the last {0}",\n "summary.hunt": "Sent adorable kitten hunters on {0} hunts",\n "summary.praise": "Accumulated {0} worship by praising the sun",\n "summary.promote": "Promoted our leader {0} times",\n "summary.refine": "Refined {0} {1}",\n "summary.separator": " and ",\n "summary.show": "Show activity",\n "summary.stars": "Observed {0} stars",\n "summary.sun": "Discovered {0} {1}",\n "summary.tech": "Researched {0}",\n "summary.time.activeHeatTransferStart": "Active Heat Transfer {0} times",\n "summary.time.getTemporalFlux": "Burn crystal to gain time flux {0} times",\n "summary.time.reset.content": "Gained {0} Karma.<br>Gained {1} Paragon",\n "summary.time.reset.title": "Summary of the last {0} timelines",\n "summary.time.skip": "Skipped {0} years",\n "summary.trade": "Traded {0} times with {1}",\n "summary.transcend": "Transcended {0} times",\n "summary.upgrade": "Upgraded {0}",\n "summary.year": "year",\n "summary.years": "years",\n "time.heatTransfer.cycle.disable": "Disabled active heat transfer in cycle {0}",\n "time.heatTransfer.cycle.enable": "Enabled active heat transfer in cycle {0}",\n "time.skip.cycle.disable": "Disabled time skip in cycle {0} and disallow skip over this cycle",\n "time.skip.cycle.enable": "Enabled time skip in cycle {0} and allow skip over this cycle",\n "time.skip.season.disable": "Disabled time skip in the {0}",\n "time.skip.season.enable": "Enabled time skip in the {0}",\n "trade.limited": "Trading with {0}: limited to only occur when profitable based off relative production time",\n "trade.season.disable": "Disabled trading with {0} in the {1}",\n "trade.season.enable": "Enabled trading with {0} in the {1}",\n "trade.seasons": "seasons",\n "trade.unlimited": "Trading with {0}: unlimited",\n "ui.additional": "Additional options",\n "ui.build": "Bonfire",\n "ui.close": "close",\n "ui.craft": "Workshop",\n "ui.craft.resources": "Resources",\n "ui.cycles": "cycles",\n "ui.disable.all": "Disable all options in this list.",\n "ui.distribute": "Village",\n "ui.enable.all": "Enable all options in this list.",\n "ui.engine": "Enable Kitten Scientists",\n "ui.faith": "Religion",\n "ui.filter": "Log Filters",\n "ui.infinity": "∞",\n "ui.internals": "Internals",\n "ui.internals.interval": "Interval: {0}",\n "ui.internals.interval.prompt": "Enter the new amount of milliseconds as an absolute value between 0 and Infinity.",\n "ui.internals.interval.promptExplainer": "All notations that the game supports are accepted. If you set the limit to 0, Kitten Scientists will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.internals.interval.promptTitle": "Kitten Scientists Execution Interval (Current: {0})",\n "ui.itemsHide": "Collapse section",\n "ui.itemsShow": "Expand section",\n "ui.ksColumn": "Display KS in fourth column in UI",\n "ui.language": "Language",\n "ui.limit": "Limited",\n "ui.limited.off": "Unlimited",\n "ui.limited.on": "Eco Mode",\n "ui.max": "Max: {0}",\n "ui.max.build.prompt": "Limit for {0} (Current: {1})",\n "ui.max.build.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.max.build.title": "Build {0} {1}",\n "ui.max.build.titleInfinite": "Never stop building {0}",\n "ui.max.build.titleZero": "Don\'t build {0}",\n "ui.max.craft.prompt": "Enter the new limit of how many {0} to craft as an absolute value between 0 and Infinity.",\n "ui.max.craft.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.max.craft.promptTitle": "Limit for Crafting {0} (Current: {1})",\n "ui.max.craft.title": "Craft {0} {1}",\n "ui.max.craft.titleInfinite": "Never stop crafting {0}",\n "ui.max.craft.titleZero": "Don\'t craft {0}",\n "ui.max.distribute.prompt": "Enter the new amount of kittens to assign as {0} as an absolute value between 0 and Infinity.",\n "ui.max.distribute.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.max.distribute.promptTitle": "Assign Max. Kittens as {0} (Current: {1})",\n "ui.max.distribute.title": "Assign {0} kittens as {1}",\n "ui.max.distribute.titleInfinite": "Assign as many kittens as possible as {0}",\n "ui.max.distribute.titleZero": "Don\'t assign any kittens as {0}",\n "ui.max.embassy.title": "Build {0} embassy for {1}",\n "ui.max.embassy.titleInfinite": "Never stop building embassies for {0}",\n "ui.max.embassy.titleZero": "Don\'t build embassies for {0}",\n "ui.max.prompt.absolute": "Enter the new limit as an absolute value between 0 and Infinity.",\n "ui.max.prompt.float": "Enter the new limit as an absolute value between 0.0 and Infinity.",\n "ui.max.set": "Maximum for {0}",\n "ui.max.timeSkip.prompt": "Enter the new amount of years as an absolute value between 0 and Infinity.",\n "ui.max.timeSkip.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.max.timeSkip.promptTitle": "Max. Years to skip (Current: {0})",\n "ui.max.timeSkip.title": "Skip {0} years at once",\n "ui.max.timeSkip.titleInfinite": "Skip as many years as possible",\n "ui.max.timeSkip.titleZero": "Don\'t skip time",\n "ui.maximum": "Maximum",\n "ui.min": "Min: {0}",\n "ui.options": "Options",\n "ui.reset": "Reset list options to default configuration.",\n "ui.resources": "Resource Control",\n "ui.space": "Space",\n "ui.time": "Time",\n "ui.timeCtrl": "Time Control",\n "ui.trade": "Trade",\n "ui.trigger": "Trigger: {0}",\n "ui.trigger.accelerateTime.prompt": "Enter the new temporal flux storage level at which to enable Tempus Fugit as a percentage between 0.0 and 100.0.",\n "ui.trigger.accelerateTime.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.accelerateTime.promptTitle": "Trigger to Accelerate Time (Current: {0})",\n "ui.trigger.activeHeatTransfer.prompt": "Enter the new temporal heat storage level at which to enable heat transfer as a percentage between 0.0 and 100.0.",\n "ui.trigger.activeHeatTransfer.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.activeHeatTransfer.promptTitle": "Trigger for Heat Transfer (Current: {0})",\n "ui.trigger.build.blocked": "∞\\n🛈 The {0} section has no trigger set. This build will not be triggered!",\n "ui.trigger.build.inherited": "inherited from section",\n "ui.trigger.build.prompt": "Trigger for {0} (Current: {1})",\n "ui.trigger.build.promptExplainer": "If you submit an empty value, or a negative value, the section trigger is used instead. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.crypto.prompt": "Enter the new relic storage level at which to trade blackcoin as an absolute value between 0.0 and Infinity.",\n "ui.trigger.crypto.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.crypto.promptTitle": "Trigger to Trade Blackcoin (Current: {0})",\n "ui.trigger.embassies.prompt": "Enter the new culture storage level at which to build embassies as a percentage between 0.0 and 100.0.",\n "ui.trigger.embassies.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.embassies.promptTitle": "Trigger to Build Embassies (Current: {0})",\n "ui.trigger.hunt.prompt": "Trigger for Hunting (Current: {0})",\n "ui.trigger.hunt.promptExplainer": "If you submit a negative value, hunting will be disabled. If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.inactive": "inactive",\n "ui.trigger.promoteKittens.prompt": "Enter the new gold storage level at which to promote kittens as a percentage between 0.0 and 100.0.",\n "ui.trigger.promoteKittens.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.promoteKittens.promptTitle": "Trigger to Promote Kittens (Current: {0})",\n "ui.trigger.prompt.absolute": "Enter the new trigger value as an absolute value between 0 and Infinity.",\n "ui.trigger.prompt.float": "Enter the new trigger value as an absolute value between 0.0 and Infinity.",\n "ui.trigger.prompt.percentage": "Enter the new trigger value as a percentage between 0.0 and 100.0.",\n "ui.trigger.reset.promptExplainer": "If you submit a negative value, the item will be disabled. If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.section": "Section default trigger: {0}",\n "ui.trigger.section.blocked": "∞\\n🛈 The {0} section has no trigger set. This automation will not be triggered!",\n "ui.trigger.section.inactive": "∞ (nothing is triggered automatically)",\n "ui.trigger.section.inherited": "inherited from section",\n "ui.trigger.section.prompt": "Trigger for section {0} (Current: {1})",\n "ui.trigger.section.promptExplainer": "If you submit an empty value, or a negative value, the section trigger will be set to infinity (∞). Individual automations in this section need to have their own trigger set to be activated.\\nIf you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.setinteger": "Enter a new trigger value for {0}. Should be in the range from 0 up to any number. -1 means infinity.",\n "ui.trigger.setinteger.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.setpercentage": "Enter a new trigger value for {0}. Should be in the range from 0 to 100.",\n "ui.trigger.setpercentage.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.timeSkip.prompt": "Enter the new amount of Time Crystals at which to skip time as an absolute value between 1 and Infinity.",\n "ui.trigger.timeSkip.promptExplainer": "If you submit a negative value, time skipping will be disabled. If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.timeSkip.promptTitle": "Trigger for Time Skip (Current: {0})",\n "ui.upgrade": "Science",\n "ui.upgrade.buildings": "Upgrade buildings",\n "ui.upgrade.missions": "Start missions",\n "ui.upgrade.policies": "Research policies",\n "ui.upgrade.races": "Explore new races",\n "ui.upgrade.techs": "Research technologies",\n "ui.upgrade.upgrades": "Research upgrades",\n "ui.upgrades": "Upgrades",\n update: update$3,\n "upgrade.building.amphitheatre": "Upgraded amphitheatres to broadcast towers!",\n "upgrade.building.aqueduct": "Upgraded aqueducts to hydro plants!",\n "upgrade.building.library": "Upgraded libraries to data centers!",\n "upgrade.building.pasture": "Upgraded pastures to solar farms!",\n "upgrade.building.warehouse": "Upgraded warehouses to spaceports!",\n "upgrade.policy": "Kittens have passed {0}",\n "upgrade.race": "Kittens met the {0}",\n "upgrade.space": "Kittens conducted a {0}",\n "upgrade.space.mission": "Kittens conducted a mission to {0}",\n "upgrade.tech": "Kittens have bought the tech {0}",\n "upgrade.upgrade": "Kittens have bought the upgrade {0}"\n };\n const copy$2 = "Kopieren";\n const reset$2 = "Zurücksetzen";\n const update$2 = "Aktualisieren";\n const deDE = {\n "act.accelerate": "Zeit beschleunigen!",\n "act.adore": "Verehre die Galaxie! Kumulierte {0} Anbetung zu {1} Offenbarung",\n "act.blackcoin.buy": "Kätzchen haben deine Relikte verkauft und {0} Blackcoins gekauft",\n "act.blackcoin.sell": "Kätzchen haben deine Blackcoins verkauft und {0} Relikte gekauft",\n "act.build": "Kätzchen haben ein neues {0} gebaut",\n "act.builds": "Kätzchen haben ein neues {0} {1} Mal gebaut",\n "act.craft": "Kätzchen haben {0} {1} hergestellt",\n "act.distribute": "Ein Kätzchen an {0} verteilt",\n "act.elect": "Kätzchen haben einen neuen Anführer gewählt.",\n "act.feed": "Kätzchen haben die Ältesten gefüttert. Die Ältesten sind zufrieden",\n "act.fix.cry": "Kätzchen haben {0} Kryokammern repariert",\n "act.hunt": "Kätzchen auf {0} Jagden entsendet",\n "act.observe": "Kitten Scientists haben einen Stern beobachtet",\n "act.praise": "Die Sonne gelobt! {0} Glaube zu {1} Anbetung kumuliert",\n "act.promote": "Der Anführer der Kätzchen wurde zum Rang {0} befördert",\n "act.refineTCs": "{0} Zeit-Kristalle verfeinert",\n "act.refineTears": "{0} Tränen zu STF verfeinert",\n "act.sacrificeAlicorns": "{0} Alihörner geopfert",\n "act.sacrificeUnicorns": "{0} Einhörner geopfert",\n "act.sun.discover": "Kätzchen haben {0} entdeckt",\n "act.sun.discovers": "Kätzchen haben {0} {1} mal entdeckt",\n "act.time.activeHeatTransferEnd": "Aktiver Wärmetransfer beendet",\n "act.time.activeHeatTransferStart": "Starte aktiven Wärmetransfer",\n "act.time.getTemporalFlux": "Verbrennt Kristalle, um Flux zur Erhaltung der Zeitbeschleunigung zu bekommen",\n "act.time.skip": "Kätzchen verbrennen einen Zeit-Kristall, {0} Jahre übersprungen!",\n "act.trade": "Kätzchen haben {0} mal mit {1} gehandelt",\n "act.transcend": "{0} Offenbarung ausgegeben, auf T-Level {1} aufgestiegen",\n "blackcoin.buy": "Kauf-Limit: {0}",\n "blackcoin.buy.prompt": "Gib den Preis ein, ab welchem du keine Blackcoins mehr kaufen möchtest.",\n "blackcoin.buy.promptExplainer": "Der Blackcoin-Preis steigt immer von 800 auf 1100 (ungefähr), dann stürzt er ab. Du möchtest normalerweise bis kurz vor dem Verkauf einkaufen.",\n "blackcoin.buy.promptTitle": "Kauf-Limit für Blackcoins (Aktuell: {0})",\n "blackcoin.buy.title": "Blackcoins kaufen bis der Preis {0} erreicht",\n "blackcoin.buy.trigger": "kaufe Blackcoins (in Relikten)",\n "blackcoin.sell": "Verkauf-Order: {0}",\n "blackcoin.sell.prompt": "Gib den Preis ein, zu welchem du deine Blackcoins verkaufen möchtest.",\n "blackcoin.sell.promptExplainer": "Der Blackcoin-Preis steigt immer von 800 auf 1100 (ungefähr), dann stürzt er ab. Du möchtest normalerweise nahe dem höchstmöglichen Preis verkaufen.",\n "blackcoin.sell.promptTitle": "Verkauf-Order für Blackcoins (Aktuell: {0})",\n "blackcoin.sell.title": "Blackcoins verkaufen, wenn der Preis {0} erreicht",\n "build.embassies": "{0} Botschaften für {1} gebaut",\n "build.embassy": "{0} Botschaft für {1} gebaut",\n copy: copy$2,\n "craft.limited": "Herstellen von {0}: im Verhältnis zum Kostenverhältnis begrenzt",\n "craft.unlimited": "Herstellung von {0}: unbegrenzt",\n "delete": "Löschen",\n "dispose.necrocorn": "Kätzchen haben ineffiziente Necrocorns entsorgt",\n "festival.extend": "Kätzchen haben das Festival verlängert",\n "festival.hold": "Kätzchen fangen an, ein Festival abzuhalten",\n "filter.accelerate": "Tempus Fugit",\n "filter.adore": "Bewundern",\n "filter.allKG": "Alle KG Protokollnachrichten.",\n "filter.build": "Bauen",\n "filter.craft": "Herstellen",\n "filter.disable": "{0} Protokollnachrichten deaktiviert",\n "filter.distribute": "Verteilen",\n "filter.enable": "{0} Protokollnachrichten aktiviert",\n "filter.explainer": "Deaktivierte Nachrichtentypen erscheinen nicht im Protokoll.",\n "filter.faith": "Orden der Sonne",\n "filter.festival": "Festivals",\n "filter.hunt": "Jagen",\n "filter.misc": "Diverses",\n "filter.praise": "Bewundern",\n "filter.promote": "Anführer befördern",\n "filter.research": "Erforschen",\n "filter.star": "Astronomische Ereignisse",\n "filter.timeSkip": "Zeitsprung",\n "filter.trade": "Handeln",\n "filter.transcend": "Transzendenz",\n "filter.upgrade": "Verbesserungen",\n "option.accelerate": "Tempus Fugit",\n "option.autofeed": "Leviathane füttern",\n "option.catnip": "Katzenminze sammeln",\n "option.crypto": "Blackcoin handeln",\n "option.elect": "Anführer benennen",\n "option.elect.job": "Beruf",\n "option.elect.job.any": "Beliebig",\n "option.elect.trait": "Eigenschaft",\n "option.embassies": "Botschaften bauen",\n "option.faith.adore": "Bewundere die Galaxie",\n "option.faith.autoPraise": "Lobe die Sonne",\n "option.faith.best.unicorn": "Reihenfolge automatisch optimieren",\n "option.faith.refineTears": "Tränen verfeinern",\n "option.faith.refineTimeCrystals": "ZKs verfeinern",\n "option.faith.sacrificeAlicorns": "Alihörner opfern",\n "option.faith.sacrificeUnicorns": "Einhörner opfern",\n "option.faith.transcend": "Transzendenz",\n "option.festival": "Festivals veranstalten",\n "option.fix.cry": "Kryokammern reparieren",\n "option.hunt": "Jagen",\n "option.magnetos": "Magnetos einschalten",\n "option.observe": "Astro-Ereignisse beobachten",\n "option.praise": "Lobe die Sonne",\n "option.promote": "Anführer befördern",\n "option.promotekittens": "Kätzchen befördern",\n "option.reactors": "Reaktoren einschalten",\n "option.shipOverride": "Erzwinge 243 Schiffe",\n "option.steamworks": "Dampfmaschinen einschalten",\n "option.time.activeHeatTransfer": "Aktiver Wärmetransfer",\n "option.time.reset": "Zeitleiste zurücksetzen (Gefahr!)",\n "option.time.skip": "Zeitsprung",\n "option.time.skip.ignoreOverheat": "Überhitzen ignorieren",\n reset: reset$2,\n "reset.after": "Schön, dich kennenzulernen, die niedlichen Kitten Scientists werden dir dienen",\n "reset.cancel.activity": "Miauston, wir haben ein Problem",\n "reset.cancel.message": "Zeitleiste zurücksetzen abgebrochen",\n "reset.check": "Auslöser für {0}: {1}, du hast {2}",\n "reset.checked": "Alle Bedingungen sind erfüllt, die Zeitlinie wird in den nächsten Sekunden neu gestartet!",\n "reset.countdown.0": "0 - Temporale Risse geöffnet!",\n "reset.countdown.1": "1 - Start der Zeitmaschine",\n "reset.countdown.2": "2 - Chronoschmiede wird beschleunigt",\n "reset.countdown.3": "3 - Zeit-Risse werden geöffnet",\n "reset.countdown.4": "4 - Satellit wird ausgeschaltet",\n "reset.countdown.5": "5 - Schmelze Blackcoins",\n "reset.countdown.6": "6 - Zeit-Motoren werden gestartet",\n "reset.countdown.7": "7 - Strahlenkanonen werden demontiert",\n "reset.countdown.8": "8 - Freisetzung von Echsen",\n "reset.countdown.9": "9 - Opfere Einhörner",\n "reset.countdown.10": "10 - Katzenminzeernte",\n "reset.last.message": "Wir sehen uns bei der nächsten poincaréschen Wiederkehr",\n "reset.tip": \'Du kannst diesen Neustart abbrechen, indem du "Kitten Scientists aktivieren" oben in den Einstellungen deaktivierst.\',\n "resources.consume": "Verbrauch: {0}",\n "resources.consume.prompt": "Gib ein wie viel von der Ressource von Automatisierungen verbraucht werden darf. Der Wert sollte zwischen 0,0 und 100,0 liegen.",\n "resources.consume.promptExplainer": "Wenn du einen leeren oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hättest.",\n "resources.consume.promptTitle": "Verbrauchsanteil für {0} (Aktuell: {1})",\n "resources.consume.set": "Verbrauchs-Rate für {0}",\n "resources.consume.title": "Verbraucht {0} von {1}",\n "resources.consume.titleZero": "{0} werden nicht verbraucht",\n "resources.stock.prompt": "Gib ein wie viel von der Ressource jederzeit im Lager bleiben soll.",\n "resources.stock.promptExplainer": "Alle Notationen, die das Spiel unterstützt werden, akzeptiert. Wenn du gar nichts, oder einen negativen Wert eingibst, wird die Grenze auf unendlich gesetzt. Wenn du die Grenze auf 0 setzt, wird Zeit Überspringen deaktiviert. Wenn du einen ungültigen Wert eingibst, wird das genauso behandelt als ob du Abbrechen gedrückt hättest.",\n "resources.stock.promptTitle": "Mindest-Lagerbestand von {0} (Aktuell: {1})",\n "resources.stock.title": "{0} {1} werden auf Lager gehalten",\n "resources.stock.titleInfinite": "Alle {0} werden auf Lager gehalten",\n "resources.stock.titleZero": "{0} werden nicht auf Lager gehalten",\n "state.compress": "Kopierte Kittens Game Spielstände komprimieren",\n "state.confirmDestruction": "Bist du sicher?",\n "state.copied.game": "Spielstand \'{0}\' in die Zwischenablage kopiert.",\n "state.copied.gameCurrent": "Aktueller Spielstand in Zwischenablage kopiert.",\n "state.copied.state": "Zustand \'{0}\' in Zwischenablage kopiert.",\n "state.copied.stateCurrent": "Aktueller Zustand wurde in die Zwischenablage kopiert.",\n "state.copy.game": "Diesen Spielstand in die Zwischenablage kopieren.",\n "state.copy.gameCurrent": "Kopiere den gesamten Kittens Game Spielstand (inklusive KS-Einstellungen) in die Zwischenablage.",\n "state.copy.state": "Diese Einstellungen in die Zwischenablage kopieren.",\n "state.copy.stateCurrent": "Kopiere die aktuellen Kitten Scientists Einstellungen in die Zwischenablage.",\n "state.delete.game": "Diesen Spielstand löschen.",\n "state.delete.state": "Diese Einstellungen löschen.",\n "state.deleted.game": "Spielstand \'{0}\' gelöscht.",\n "state.deleted.state": "Zustand \'{0}\' gelöscht.",\n "state.edit.game": "Ändere den Namen von diesem Spielstand.",\n "state.edit.state": "Ändere den Namen von diesen Einstellungen.",\n "state.exportAll": "Export",\n "state.exportAllTitle": "Speichert alle lokalen Zustände in einer Datei und lädt sie herunter.",\n "state.import": "Einstellungen/Spielstände importieren",\n "state.imported.game": "Spielstand importiert.",\n "state.imported.state": "Zustand importiert.",\n "state.importedState": "Importierter Stand {0}",\n "state.importTitle": "Füge ein Spielstand oder Einstellungen aus deiner Zwischenablage ein.\\nInhalte werden automatisch erkannt und entsprechend behandelt.",\n "state.loaded.game": "Spielstand \'{0}\' geladen.",\n "state.loaded.state": "Zustand \'{0}\' geladen.",\n "state.loadPrompt": "Füge deinen (un/komprimierten) Spielstand oder deine Einstellungen hier ein:",\n "state.local": "Lokale Speicherverwaltung",\n "state.localGames": "Kittens Game Spielstände",\n "state.localStates": "Kitten Scientists Einstellungen",\n "state.new": "Neu",\n "state.noConfirm": "Nicht nach Bestätigung fragen",\n "state.store": "Speichern",\n "state.stored.game": "Spielstand gespeichert.",\n "state.stored.state": "Zustand gespeichert.",\n "state.storeFactory": "Neuen Zustand aus Werkseinstellungen erstellen.",\n "state.storeGame": "Neuen Spielstand vom aktuellen Spiel erstellen.",\n "state.storeGame.prompt": "Gib eine Beschreibung für diesen Spielstand ein:",\n "state.storeState": "Erstelle einen neuen Zustand aus den aktuellen Einstellungen.",\n "state.storeState.prompt": "Gib eine Beschreibung für diesen Zustand ein:",\n "state.title": "Zustandsverwaltung",\n "state.unlabeledGame": "unbeschriftetes Spiel",\n "state.unlabeledState": "unbeschrifteter Zustand",\n "state.update.game": "Speichere das aktuelle Spiel in diesem Slot.",\n "state.update.state": "Speichere die aktuellen Einstellungen in diesem Slot.",\n "state.updated.game": "Spielstand \'{0}\' aktualisiert.",\n "state.updated.state": "Zustand \'{0}\' aktualisiert.",\n "status.auto.disable": "Auto {0} deaktiviert",\n "status.auto.enable": "Auto {0} aktiviert",\n "status.ks.disable": "Deaktiviere die Kitten Scientists!",\n "status.ks.enable": "Aktiviere die Kitten Scientists!",\n "status.ks.init": "Kitten Scientists initialisiert.",\n "status.ks.upgrade": "Kitten Scientists {0} (unsere ist {1}) ist unter {2} verfügbar.",\n "status.reset.check.disable": "Überprüfung von {0} vor dem Zurücksetzen der Zeitlinie deaktiviert",\n "status.reset.check.enable": "Überprüfung von {0} vor dem Zurücksetzen der Zeitlinie aktiviert",\n "status.resource.disable": "{0} Ressourcenverwaltung deaktiviert",\n "status.resource.enable": "{0} Ressourcenverwaltung aktiviert",\n "status.sub.disable": "{0} deaktiviert",\n "status.sub.enable": "{0} aktiviert",\n "summary.accelerate": "Zeit {0} Mal beschleunigt",\n "summary.adore": "{0} Offenbarung durch das Bewundern der Galaxie akkumuliert",\n "summary.building": "{0} {1} gebaut",\n "summary.craft": "{0} {1} hergestellt",\n "summary.day": "Tag",\n "summary.days": "Tage",\n "summary.distribute": "{0} Kätzchen geholfen einen Beruf zu finden",\n "summary.embassy": "{0} Botschaften gebaut",\n "summary.feed": "{0} Necrocorns an die Ältesten verfüttert",\n "summary.festival": "{0} Festivals veranstaltet",\n "summary.fix.cry": "{0} Kryokammern repariert",\n "summary.head": "Zusammenfassung der letzten {0}",\n "summary.hunt": "Niedliche Jäger Kätzchen auf {0} Jagden versandt",\n "summary.praise": "{0} Anbetung durch Loben der Sonne akkumuliert",\n "summary.promote": "Unseren Anführer {0} mal befördert",\n "summary.refine": "{0} {1} verfeinert",\n "summary.separator": " und ",\n "summary.show": "Aktivitäten anzeigen",\n "summary.stars": "{0} Sterne beobachtet",\n "summary.sun": "{0} {1} entdeckt",\n "summary.tech": "{0} erforscht",\n "summary.time.activeHeatTransferStart": "Aktive Wärmeübertragung {0} mal",\n "summary.time.getTemporalFlux": "{0} Mal Kristalle verbrannt, um Zeit Flux zu generieren",\n "summary.time.reset.content": "{0} Karma erhalten.<br>{1} Paragon erhalten",\n "summary.time.reset.title": "Zusammenfassung der letzten {0} Zeitleisten",\n "summary.time.skip": "{0} Jahre übersprungen",\n "summary.trade": "{0} mal mit {1} gehandelt",\n "summary.transcend": "{0} mal aufgestiegen",\n "summary.upgrade": "{0} verbessert",\n "summary.year": "Jahr",\n "summary.years": "Jahre",\n "time.heatTransfer.cycle.disable": "Aktiver Wärmetransfer im Zyklus {0} deaktiviert",\n "time.heatTransfer.cycle.enable": "Aktiver Wärmetransfer im Zyklus {0} aktiviert",\n "time.skip.cycle.disable": "Zeitsprung im Zyklus {0} und Überspringen über diesen Zyklus verboten",\n "time.skip.cycle.enable": "Zeitsprung im Zyklus {0} und Überspringen über diesen Zyklus erlaubt",\n "time.skip.season.disable": "Zeitsprung in {0} deaktiviert",\n "time.skip.season.enable": "Zeitsprung in {0} aktiviert",\n "trade.limited": "Handel mit {0}: limitiert auf nur, wenn profitabel auf Basis der relativen Produktionszeit",\n "trade.season.disable": "Handel mit {0} in {1} deaktiviert",\n "trade.season.enable": "Handel mit {0} in {1} aktiviert",\n "trade.seasons": "Jahreszeiten",\n "trade.unlimited": "Handel mit {0}: unbegrenzt",\n "ui.additional": "Weitere Optionen",\n "ui.build": "Lagerfeuer",\n "ui.close": "schließen",\n "ui.craft": "Werkstatt",\n "ui.craft.resources": "Ressourcen",\n "ui.cycles": "Zyklen",\n "ui.disable.all": "Alle Optionen in dieser Liste deaktivieren.",\n "ui.distribute": "Dorf",\n "ui.enable.all": "Alle Optionen in dieser Liste aktivieren.",\n "ui.engine": "Kitten Scientists aktivieren",\n "ui.faith": "Religion",\n "ui.filter": "Protokollfilter",\n "ui.infinity": "∞",\n "ui.internals": "Intern",\n "ui.internals.interval": "Intervall: {0}",\n "ui.internals.interval.prompt": "Gib die neue Anzahl an Millisekunden als absoluten Wert zwischen 0 und unendlich ein.",\n "ui.internals.interval.promptExplainer": "Alle Notationen, die das Spiel unterstützt werden, akzeptiert. Wenn du die Grenze auf 0 setzt, werden die Kitten Scientists deaktiviert. Wenn du einen ungültigen Wert eingibst, wird das genauso behandelt als ob du Abbrechen gedrückt hättest.",\n "ui.internals.interval.promptTitle": "Kitten Scientists Ausführungsintervall (Aktuell: {0})",\n "ui.itemsHide": "Abschnitt einklappen",\n "ui.itemsShow": "Abschnitt ausklappen",\n "ui.ksColumn": "KS in vierter Spalte im UI anzeigen",\n "ui.language": "Sprache",\n "ui.limit": "Begrenzt",\n "ui.limited.off": "Unbegrenzt",\n "ui.limited.on": "Öko-Modus",\n "ui.max": "Max: {0}",\n "ui.max.build.prompt": "Grenze für {0} (Aktuell: {1})",\n "ui.max.build.promptExplainer": "Alle Notationen, die das Spiel unterstützt werden, akzeptiert. Wenn du gar nichts, oder einen negativen Wert eingibst, wird die Grenze auf unendlich gesetzt. Wenn du die Grenze auf 0 setzt, wird Zeit Überspringen deaktiviert. Wenn du einen ungültigen Wert eingibst, wird das genauso behandelt als ob du Abbrechen gedrückt hättest.",\n "ui.max.build.title": "Baue {0} {1}",\n "ui.max.build.titleInfinite": "Nie aufhören {0} zu bauen",\n "ui.max.build.titleZero": "{0} nicht bauen",\n "ui.max.craft.prompt": "Gib die neue Grenze zum Herstellen von {0} als absoluten Wert zwischen 0 und unendlich ein.",\n "ui.max.craft.promptExplainer": "Alle Notationen, die das Spiel unterstützt werden, akzeptiert. Wenn du gar nichts, oder einen negativen Wert eingibst, wird die Grenze auf unendlich gesetzt. Wenn du die Grenze auf 0 setzt, wird Zeit Überspringen deaktiviert. Wenn du einen ungültigen Wert eingibst, wird das genauso behandelt als ob du Abbrechen gedrückt hättest.",\n "ui.max.craft.promptTitle": "Grenze für Herstellen von {0} (Aktuell: {1})",\n "ui.max.craft.title": "{0} {1} herstellen",\n "ui.max.craft.titleInfinite": "Nie aufhören {0} herzustellen",\n "ui.max.craft.titleZero": "{0} nicht herstellen",\n "ui.max.distribute.prompt": "Gib die neue Anzahl an Kätzchen im {0} Beruf als absoluten Wert zwischen 0 und unendlich ein.",\n "ui.max.distribute.promptExplainer": "Alle Notationen, die das Spiel unterstützt werden, akzeptiert. Wenn du gar nichts, oder einen negativen Wert eingibst, wird die Grenze auf unendlich gesetzt. Wenn du die Grenze auf 0 setzt, wird Zeit Überspringen deaktiviert. Wenn du einen ungültigen Wert eingibst, wird das genauso behandelt als ob du Abbrechen gedrückt hättest.",\n "ui.max.distribute.promptTitle": "Max. Kätzchen als {0} zuweisen (Aktuell: {1})",\n "ui.max.distribute.title": "{0} Kätzchen als {1} zuweisen",\n "ui.max.distribute.titleInfinite": "So viele Kätzchen wie möglich als {0} zuweisen",\n "ui.max.distribute.titleZero": "Keine Kätzchen als {0} zuweisen",\n "ui.max.embassy.title": "Baue {0} Botschaften für {1}",\n "ui.max.embassy.titleInfinite": "Nie aufhören Botschaften für {0} zu bauen",\n "ui.max.embassy.titleZero": "Keine Botschaften für {0} bauen",\n "ui.max.prompt.absolute": "Gib die neue Grenze als absoluten Wert zwischen 0 und unendlich ein.",\n "ui.max.prompt.float": "Gib die neue Grenze als absoluten Wert zwischen 0,0 und unendlich ein.",\n "ui.max.set": "Maximum für {0}",\n "ui.max.timeSkip.prompt": "Gib die neue Anzahl an Jahren als absoluten Wert zwischen 0 und unendlich ein.",\n "ui.max.timeSkip.promptExplainer": "Alle Notationen, die das Spiel unterstützt werden, akzeptiert. Wenn du gar nichts, oder einen negativen Wert eingibst, wird die Grenze auf unendlich gesetzt. Wenn du die Grenze auf 0 setzt, wird Zeit Überspringen deaktiviert. Wenn du einen ungültigen Wert eingibst, wird das genauso behandelt als ob du Abbrechen gedrückt hättest.",\n "ui.max.timeSkip.promptTitle": "Max. Jahre zum Überspringen (Aktuell: {0})",\n "ui.max.timeSkip.title": "{0} Jahre auf einmal überspringen",\n "ui.max.timeSkip.titleInfinite": "So viele Jahre wie möglich überspringen",\n "ui.max.timeSkip.titleZero": "Keine Zeit überspringen",\n "ui.maximum": "Maximum",\n "ui.min": "Min. {0}",\n "ui.options": "Optionen",\n "ui.reset": "Optionen in der Liste auf Standardkonfiguration zurücksetzen.",\n "ui.resources": "Ressourcensteuerung",\n "ui.space": "Weltraum",\n "ui.time": "Zeit",\n "ui.timeCtrl": "Zeitsteuerung",\n "ui.trade": "Handel",\n "ui.trigger": "Auslöser: {0}",\n "ui.trigger.accelerateTime.prompt": "Gib den neuen Lagerbestand von Temporalem Flux, bei welchem Tempus Fugit aktiviert werden soll, als Prozentzahl ein. Der Wert sollte zwischen 0,0 und 100,0 liegen.",\n "ui.trigger.accelerateTime.promptExplainer": "Wenn du einen leeren oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hättest.",\n "ui.trigger.accelerateTime.promptTitle": "Auslöser zur Zeit-Beschleunigung (Aktuell: {0})",\n "ui.trigger.activeHeatTransfer.prompt": "Gib den neuen Stand von Chronohitze, bei welchem aktiver Wärmetransfer aktiviert werden sollen, als Prozentzahl ein. Der Wert sollte zwischen 0,0 und 100,0 liegen.",\n "ui.trigger.activeHeatTransfer.promptExplainer": "Wenn du einen leeren oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hättest.",\n "ui.trigger.activeHeatTransfer.promptTitle": "Auslöser für Wärmetransfer (Aktuell: {0})",\n "ui.trigger.build.blocked": "∞\\n🛈 Der Abschnitt {0} hat keinen Auslöser gesetzt. Diese Option wird nie ausgelöst!",\n "ui.trigger.build.inherited": "von Abschnitt übernommen",\n "ui.trigger.build.prompt": "Auslöser für {0} (Aktuell: {1})",\n "ui.trigger.build.promptExplainer": \'Wenn du gar nichts, oder eine negative Zahl eingibst, wird der Auslöser des Abschnitts geerbt. Ungültige Eingaben werden so behandelt als ob du "Abbrechen" drückst.\',\n "ui.trigger.crypto.prompt": "Gib den neuen Lagerbestand von Relikten, bei welchem Blackcoins gehandelt werden sollen, als absoluten Wert zwischen 0,0 und unendlich ein.",\n "ui.trigger.crypto.promptExplainer": "Wenn du einen leeren oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hättest.",\n "ui.trigger.crypto.promptTitle": "Auslöser um Blackcoin zu handeln (Aktuell: {0})",\n "ui.trigger.embassies.prompt": "Gib den neuen Lagerbestand von Kultur, bei welchem Botschaften gebaut werden sollen, als Prozentzahl ein. Der Wert sollte zwischen 0,0 und 100,0 liegen.",\n "ui.trigger.embassies.promptExplainer": "Wenn du einen leeren oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hättest.",\n "ui.trigger.embassies.promptTitle": "Auslöser für den Bau von Botschaften (Aktuell: {0})",\n "ui.trigger.hunt.prompt": "Auslöser für Jagd (Aktuell: {0})",\n "ui.trigger.hunt.promptExplainer": "Wenn du einen negativen Wert eingibst, wird Jagen deaktiviert. Wenn du einen leeren Wert oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hast.",\n "ui.trigger.inactive": "inaktiv",\n "ui.trigger.promoteKittens.prompt": "Gib den neuen Lagerbestand von Gold, bei welchem Kätzchen befördert werden sollen, als Prozentzahl ein. Der Wert sollte zwischen 0,0 und 100,0 liegen.",\n "ui.trigger.promoteKittens.promptExplainer": "Wenn du einen leeren oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hättest.",\n "ui.trigger.promoteKittens.promptTitle": "Auslöser um Kätzchen zu befördern (Aktuell: {0})",\n "ui.trigger.prompt.absolute": "Gib den neuen Auslöser als absoluten Wert zwischen 0 und unendlich ein.",\n "ui.trigger.prompt.float": "Gib den neuen Auslöser als absoluten Wert zwischen 0,0 und unendlich ein.",\n "ui.trigger.prompt.percentage": "Gib den neuen Auslöser als Prozentzahl zwischen 0,0 und 100,0 ein.",\n "ui.trigger.reset.promptExplainer": "Wenn du einen negativen Wert eingibst, wird die Option deaktiviert. Wenn du einen leeren Wert oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hast.",\n "ui.trigger.section": "Abschnitt Standard-Auslöser: {0}",\n "ui.trigger.section.blocked": "∞\\n🛈 Der Abschnitt {0} hat keinen Auslöser gesetzt. Diese Option wird nie ausgelöst!",\n "ui.trigger.section.inactive": "∞ (nichts wird automatisch ausgelöst)",\n "ui.trigger.section.inherited": "von Abschnitt übernommen",\n "ui.trigger.section.prompt": "Auslöser für Abschnitt {0} (Aktuell: {1})",\n "ui.trigger.section.promptExplainer": \'Wenn du einen leeren Wert oder einen negativen Wert eingibst, wird der Auslöser des Abschnitts auf Unendlichkeit gesetzt (∞), was alle Optionen deaktiviert, es sei denn, sie haben einen eigenen Auslöser gesetzt.\\nWenn du einen ungültigen Wert eingibst, wird er so behandelt, als ob du "Abbrechen" drückst.\',\n "ui.trigger.setinteger": "Gib einen neuen Auslöser für {0} ein. Sollte im Bereich von 0 bis zu einer beliebigen Zahl liegen. -1 bedeutet unendlich.",\n "ui.trigger.setinteger.promptExplainer": "Wenn du einen leeren oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hättest.",\n "ui.trigger.setpercentage": "Geben Sie einen neuen Auslöser für {0} ein. Sollte im Bereich von 0 bis 100 liegen.",\n "ui.trigger.setpercentage.promptExplainer": "Wenn du einen leeren oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hättest.",\n "ui.trigger.timeSkip.prompt": "Gib die neue Menge an Zeitkristallen ein, bei welcher Zeit übersprungen werden soll. Der Wert sollte zwischen 1 und unendlich liegen.",\n "ui.trigger.timeSkip.promptExplainer": "Wenn du einen negativen Wert eingibst, werden Zeit-Sprünge deaktiviert. Wenn du einen leeren Wert oder einen ungültigen Wert eingibst, wird das so behandelt, als ob du Abbrechen gedrückt hast.",\n "ui.trigger.timeSkip.promptTitle": "Auslöser für Zeitsprung (Aktuell: {0})",\n "ui.upgrade": "Wissenschaft",\n "ui.upgrade.buildings": "Gebäude verbessern",\n "ui.upgrade.missions": "Missionen starten",\n "ui.upgrade.policies": "Politik erforschen",\n "ui.upgrade.races": "Neue Völker erforschen",\n "ui.upgrade.techs": "Technologien erforschen",\n "ui.upgrade.upgrades": "Verbesserungen erforschen",\n "ui.upgrades": "Verbesserungen",\n update: update$2,\n "upgrade.building.amphitheatre": "Amphitheater zu Sendetürmen verbessert!",\n "upgrade.building.aqueduct": "Aquädukte zu Wasserwerken verbessert!",\n "upgrade.building.library": "Bibliotheken zu Rechenzentren verbessert!",\n "upgrade.building.pasture": "Weiden zu Solarfarmen verbessert!",\n "upgrade.building.warehouse": "Lagerhäuser zu Raumhäfen verbessert!",\n "upgrade.policy": "Kätzchen haben {0} veranlasst",\n "upgrade.race": "Kätzchen haben die {0} getroffen",\n "upgrade.space": "Kätzchen haben {0} durchgeführt",\n "upgrade.space.mission": "Kätzchen haben eine Mission zu {0} durchgeführt",\n "upgrade.tech": "Kätzchen haben die Technologie {0} gekauft",\n "upgrade.upgrade": "Kätzchen haben die Verbesserung {0} gekauft"\n };\n const copy$1 = "Copy";\n const reset$1 = "Reset";\n const update$1 = "Update";\n const heIL = {\n "act.accelerate": "האץ את הזמן!",\n "act.adore": "העריץ את הגלקסיה! נאסף {0} פולחן ל-{1} תגלית",\n "act.blackcoin.buy": "Kittens sold your Relics and bought {0} Blackcoins",\n "act.blackcoin.sell": "Kittens sold your Blackcoins and bought {0} Relics",\n "act.build": "חתלתולים בנו {0} חדש",\n "act.builds": "חתלתולים בנו {0} חדש {1} פעמים",\n "act.craft": "חתלתולים יצרו {0} {1}",\n "act.distribute": "הופץ חתלתול ל-{0}",\n "act.elect": "חתלתולים בחרו מנהיג חדש.",\n "act.feed": "חתלתולים האכילו את העתיקים. העתיקים מרוצים",\n "act.fix.cry": "חתלתולים תיקנו {0} תאי קריו",\n "act.hunt": "נשלחו חתלתולים {0} פעמים לציד",\n "act.observe": "מדעניתלתול צפו בכוכב",\n "act.praise": "הריעו לשמש! נצבר {0} אמונה עבור {1} פולחן",\n "act.promote": "מנהיג החתלתולים קודם לדרגה {0}",\n "act.refineTCs": "זוקקו {0} בדולחי זמן",\n "act.refineTears": "Refined {0} tears into BLS",\n "act.sacrificeAlicorns": "הוקרבו {0} מכונפי קרן",\n "act.sacrificeUnicorns": "Sacrificed {0} unicorns",\n "act.sun.discover": "חתותולים גילו {0}",\n "act.sun.discovers": "חתלתולים גילו {0} {1} פעמים",\n "act.time.activeHeatTransferEnd": "End active Heat Transfer",\n "act.time.activeHeatTransferStart": "Start active Heat Transfer",\n "act.time.getTemporalFlux": "Burn crystals to obtain time flux to maintain time acceleration",\n "act.time.skip": "חתלתולים שרפו בדולח זמן, ופסחו על {0} שנים!",\n "act.trade": "חתלתולים סחרו {0} פעמים עם {1}",\n "act.transcend": "נוצל {0} תגלית, התעלה לרמת התעלות: {1}",\n "blackcoin.buy": "Buy Limit: {0}",\n "blackcoin.buy.prompt": "Enter at which price you want to stop buying blackcoins.",\n "blackcoin.buy.promptExplainer": "Blackcoin price always rises from 800 to 1100 (roughly), then it crashes. You usually want to buy until shortly before you sell.",\n "blackcoin.buy.promptTitle": "Buy Limit for Blackcoins (Current: {0})",\n "blackcoin.buy.title": "Buy Blackcoins until price reaches {0}",\n "blackcoin.buy.trigger": "קונה מטבעותשחור (בשרידים)",\n "blackcoin.sell": "Sell Order: {0}",\n "blackcoin.sell.prompt": "Enter at which price you want to sell all your blackcoins.",\n "blackcoin.sell.promptExplainer": "Blackcoin price always rises from 800 to 1100 (roughly), then it crashes. You usually want to sell close to the highest possible price.",\n "blackcoin.sell.promptTitle": "Sell Order for Blackcoins (Current: {0})",\n "blackcoin.sell.title": "Sell Blackcoins when price reaches {0}",\n "build.embassies": "נבנו {0} שגרירויות של {1}",\n "build.embassy": "נבנו {0} שגרירויות של {1}",\n copy: copy$1,\n "craft.limited": "יוצר {0}: מוגבל לעלות היחסית",\n "craft.unlimited": "יוצר {0}: ללא הגבלה",\n "delete": "Delete",\n "dispose.necrocorn": "חתלתולים נפטרו מאלמתי קרן לא יעילים",\n "festival.extend": "חתלתולים האריכו את החגיגה",\n "festival.hold": "חתלתולים החלו לערוך חגיגה",\n "filter.accelerate": "הזמן עובר לו",\n "filter.adore": "מעריץ",\n "filter.allKG": "All KG log entries.",\n "filter.build": "בנייה",\n "filter.craft": "יצירה",\n "filter.disable": "נכבו {0} רשומות",\n "filter.distribute": "חלוקה",\n "filter.enable": "Enabled {0} log messages",\n "filter.explainer": "Disabled items are hidden from the log.",\n "filter.faith": "מסדר השמש",\n "filter.festival": "חגיגות",\n "filter.hunt": "ציד",\n "filter.misc": "שונות",\n "filter.praise": "הילול",\n "filter.promote": "העלאות דרגה",\n "filter.research": "חקר",\n "filter.star": "אירועים אסטרונומיים",\n "filter.timeSkip": "קפיצת זמן",\n "filter.trade": "סחר",\n "filter.transcend": "עילוי",\n "filter.upgrade": "שדרוג",\n "option.accelerate": "הזמן עובר לו",\n "option.autofeed": "האכל לוויתנים",\n "option.catnip": "Gather Catnip",\n "option.crypto": "סחור במטבעשחור",\n "option.elect": "בחר מנהיג",\n "option.elect.job": "Job",\n "option.elect.job.any": "Any",\n "option.elect.trait": "Trait",\n "option.embassies": "בנה שגרירויות",\n "option.faith.adore": "הערץ את הגלקסיה",\n "option.faith.autoPraise": "הלל את השמש",\n "option.faith.best.unicorn": "Automate Build Order",\n "option.faith.refineTears": "זקק דמעות",\n "option.faith.refineTimeCrystals": "זקק TCים",\n "option.faith.sacrificeAlicorns": "הקרב מכונפי קרן",\n "option.faith.sacrificeUnicorns": "Sacrifice Unicorns",\n "option.faith.transcend": "עילוי",\n "option.festival": "ארגן חגיגות",\n "option.fix.cry": "תקן תאי קריו",\n "option.hunt": "צוד",\n "option.magnetos": "הפעל מגנטוים",\n "option.observe": "צפה באירועים אסטרונומיים",\n "option.praise": "הלל את השמש",\n "option.promote": "העלאות דרגה",\n "option.promotekittens": "העלה את דרגת החתלתולים",\n "option.reactors": "Turn on Reactors",\n "option.shipOverride": "הכרח ספינות ל-243",\n "option.steamworks": "הפעל את מנוע הקיטור",\n "option.time.activeHeatTransfer": "Active Heat Transfer",\n "option.time.reset": "אתחל מחדש את ציר הזמן (סכנה!)",\n "option.time.skip": "קפיצת זמן",\n "option.time.skip.ignoreOverheat": "Ignore overheat",\n reset: reset$1,\n "reset.after": "Nice to meet you, the cute Kitten Scientists will serve you",\n "reset.cancel.activity": "מאוסטון, יש לנו בעיה",\n "reset.cancel.message": "אתחול ציר הזמן בוטל",\n "reset.check": "Trigger for {0}: {1}, you have {2}",\n "reset.checked": "All conditions are met, the timeline will restart in the next few seconds!",\n "reset.countdown.0": "0 - Temporal rifts opened!",\n "reset.countdown.1": "1 - Time engine start",\n "reset.countdown.2": "2 - Boosting the chronoforge",\n "reset.countdown.3": "3 - Opening temporal rifts",\n "reset.countdown.4": "4 - Turning off satellite",\n "reset.countdown.5": "5 - Melting blackcoins",\n "reset.countdown.6": "6 - Starting time engines",\n "reset.countdown.7": "7 - Disassembling railguns",\n "reset.countdown.8": "8 - Releasing lizards",\n "reset.countdown.9": "9 - Sacrificing unicorns",\n "reset.countdown.10": "10 - קוצר נפית חתולים",\n "reset.last.message": "נתראה בהישנות פואנקרה הבאה",\n "reset.tip": \'You can cancel this reset by disabling "Enable Kitten Scientists" at the top of the settings.\',\n "resources.consume": "צרוך: {0}",\n "resources.consume.prompt": "Enter how much of the resource you want automations to consume as a percentage between 0.0 and 100.0.",\n "resources.consume.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "resources.consume.promptTitle": "Consumption Share for {0} (Current: {1})",\n "resources.consume.set": "קצב צריכה עבור {0}",\n "resources.consume.title": "Consuming {0} of {1}",\n "resources.consume.titleZero": "Not consuming {0}",\n "resources.stock.prompt": "Enter how much of the resource you always want to keep in stock.",\n "resources.stock.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "resources.stock.promptTitle": "Stock value for {0} (Current: {1})",\n "resources.stock.title": "Keeping {0} {1} in stock",\n "resources.stock.titleInfinite": "Keeping all {0} in stock",\n "resources.stock.titleZero": "Not keeping any {0} in stock",\n "state.compress": "Compress data",\n "state.confirmDestruction": "האם אתה בטוח?",\n "state.copied.game": "Save \'{0}\' copied to clipboard.",\n "state.copied.gameCurrent": "Current save copied to clipboard.",\n "state.copied.state": "State \'{0}\' copied to clipboard.",\n "state.copied.stateCurrent": "Current state copied to clipboard.",\n "state.copy.game": "Copy this save to the clipboard.",\n "state.copy.gameCurrent": "Copy the entire Kittens Game save (includes KS settings) to the clipboard.",\n "state.copy.state": "Copy these settings to the clipboard.",\n "state.copy.stateCurrent": "Copy the current Kitten Scientists settings to the clipboard.",\n "state.delete.game": "Delete this save.",\n "state.delete.state": "Delete these settings.",\n "state.deleted.game": "Save \'{0}\' deleted.",\n "state.deleted.state": "State \'{0}\' deleted.",\n "state.edit.game": "Change the name of this save.",\n "state.edit.state": "Change the name of these settings.",\n "state.exportAll": "Backup",\n "state.exportAllTitle": "Stores all local states in a single file and downloads it.",\n "state.import": "Import from clipboard",\n "state.imported.game": "Save imported.",\n "state.imported.state": "State imported.",\n "state.importedState": "Imported state {0}",\n "state.importTitle": "Paste a save or settings from your clipboard.\\nContents will be automatically detected and handled accordingly.",\n "state.loaded.game": "Save \'{0}\' loaded.",\n "state.loaded.state": "State \'{0}\' loaded.",\n "state.loadPrompt": "Paste your (un/compressed) save or settings here:",\n "state.local": "Local states",\n "state.localGames": "Kittens Game Saves",\n "state.localStates": "Kitten Scientists Settings",\n "state.new": "New",\n "state.noConfirm": "Do NOT confirm destructive actions. (Danger!)",\n "state.store": "Store",\n "state.stored.game": "Save stored.",\n "state.stored.state": "State stored.",\n "state.storeFactory": "Create a new state from factory defaults.",\n "state.storeGame": "Create a new save from the current game.",\n "state.storeGame.prompt": "Provide a label for this save:",\n "state.storeState": "Create a new state from current settings.",\n "state.storeState.prompt": "Provide a label for this state:",\n "state.title": "State Management",\n "state.unlabeledGame": "unlabeled save",\n "state.unlabeledState": "unlabeled state",\n "state.update.game": "Save the current game into this slot.",\n "state.update.state": "Save the current settings into this slot.",\n "state.updated.game": "Save \'{0}\' updated.",\n "state.updated.state": "State \'{0}\' updated.",\n "status.auto.disable": "Disabled Auto {0}",\n "status.auto.enable": "Enabled Auto {0}",\n "status.ks.disable": "מבטל את המדעניתלתול!",\n "status.ks.enable": "מאפשר את המדעניתלתול!",\n "status.ks.init": "Kitten Scientists initialized.",\n "status.ks.upgrade": "Kitten Scientists {0} (ours is {1}) is available at {2}.",\n "status.reset.check.disable": "Disabled check {0} before Reset Timeline",\n "status.reset.check.enable": "Enabled check {0} before Reset Timeline",\n "status.resource.disable": "כבה ניהול משאבי {0}",\n "status.resource.enable": "הפעל ניהול משאבי {0}",\n "status.sub.disable": "{0} הושבת",\n "status.sub.enable": "{0} אופשר",\n "summary.accelerate": "הזמן הועץ {0} פעמים",\n "summary.adore": "נצבר {0} תגלית על ידי הערצת הגלקסיה",\n "summary.building": "נבנה {0} {1}",\n "summary.craft": "נוצר {0} {1}",\n "summary.day": "יום",\n "summary.days": "ימים",\n "summary.distribute": "עזרת ל-{0} חתלתולים למצוא עבודה",\n "summary.embassy": "נבנו {0} שגרירויות",\n "summary.feed": "האכלת את הוותיקים {0} אלמתי קרן",\n "summary.festival": "אורגנו {0} חגיגות",\n "summary.fix.cry": "תוקנו {0} תאי קריו",\n "summary.head": "תקציר {0} האחרונים",\n "summary.hunt": "צידיתלתול יצאו לצוד {0} פעמים",\n "summary.praise": "נצבר {0} פולחן על ידי הילול השמש",\n "summary.promote": "המנהיג קודם {0} פעמים",\n "summary.refine": "זוקק {0} {1}",\n "summary.separator": " ועוד ",\n "summary.show": "הצג פעילות",\n "summary.stars": "נצפו {0} כוכבים",\n "summary.sun": "התגלו {0} {1}",\n "summary.tech": "נחקרו {0}",\n "summary.time.activeHeatTransferStart": "Active Heat Transfer {0} times",\n "summary.time.getTemporalFlux": "Burn crystal to gain time flux {0} times",\n "summary.time.reset.content": "נאסף {0} קרמה.<br>נאסף {1} מופת",\n "summary.time.reset.title": "סיכום {0} צירי הזמן האחרונים",\n "summary.time.skip": "{0} שנים נפסחו",\n "summary.trade": "סחרת {0} פעמים עם {1}",\n "summary.transcend": "התעלית {0} פעמים",\n "summary.upgrade": "שודרג {0}",\n "summary.year": "שנה",\n "summary.years": "שנים",\n "time.heatTransfer.cycle.disable": "Disabled active heat transfer in cycle {0}",\n "time.heatTransfer.cycle.enable": "Enabled active heat transfer in cycle {0}",\n "time.skip.cycle.disable": "Disabled time skip in cycle {0} and disallow skip over this cycle",\n "time.skip.cycle.enable": "Enabled time skip in cycle {0} and allow skip over this cycle",\n "time.skip.season.disable": "Disabled time skip in the {0}",\n "time.skip.season.enable": "Enabled time skip in the {0}",\n "trade.limited": "סחר עם {0}: מוגבל רק כאשר זה רווחי ביחס לזמן ייצור",\n "trade.season.disable": "בוטל הסחר עם {0} עבור {1}",\n "trade.season.enable": "אופשר הסחר עם {0} עבור {1}",\n "trade.seasons": "עונות",\n "trade.unlimited": "סחר עם {0}: ללא הגבלה",\n "ui.additional": "Additional options",\n "ui.build": "מדורה",\n "ui.close": "סגור",\n "ui.craft": "סדנא",\n "ui.craft.resources": "משאבים",\n "ui.cycles": "מחזורים",\n "ui.disable.all": "Disable all options in this list.",\n "ui.distribute": "כפר",\n "ui.enable.all": "Enable all options in this list.",\n "ui.engine": "Enable Kitten Scientists",\n "ui.faith": "דת",\n "ui.filter": "סנני רשומות",\n "ui.infinity": "∞",\n "ui.internals": "Internals",\n "ui.internals.interval": "Interval: {0}",\n "ui.internals.interval.prompt": "Enter the new amount of milliseconds as an absolute value between 0 and Infinity.",\n "ui.internals.interval.promptExplainer": "All notations that the game supports are accepted. If you set the limit to 0, Kitten Scientists will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.internals.interval.promptTitle": "Kitten Scientists Execution Interval (Current: {0})",\n "ui.itemsHide": "Collapse section",\n "ui.itemsShow": "Expand section",\n "ui.ksColumn": "Display in fourth column",\n "ui.language": "Language",\n "ui.limit": "מוגבל",\n "ui.limited.off": "Unlimited",\n "ui.limited.on": "Eco Mode",\n "ui.max": "מירבי: {0}",\n "ui.max.build.prompt": "Limit for {0} (Current: {1})",\n "ui.max.build.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.max.build.title": "Build {0} {1}",\n "ui.max.build.titleInfinite": "Never stop building {0}",\n "ui.max.build.titleZero": "Don\'t build {0}",\n "ui.max.craft.prompt": "Enter the new limit of how many {0} to craft as an absolute value between 0 and Infinity.",\n "ui.max.craft.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.max.craft.promptTitle": "Limit for Crafting {0} (Current: {1})",\n "ui.max.craft.title": "Craft {0} {1}",\n "ui.max.craft.titleInfinite": "Never stop crafting {0}",\n "ui.max.craft.titleZero": "Don\'t craft {0}",\n "ui.max.distribute.prompt": "Enter the new amount of kittens to assign as {0} as an absolute value between 0 and Infinity.",\n "ui.max.distribute.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.max.distribute.promptTitle": "Assign Max. Kittens as {0} (Current: {1})",\n "ui.max.distribute.title": "Assign {0} kittens as {1}",\n "ui.max.distribute.titleInfinite": "Assign as many kittens as possible as {0}",\n "ui.max.distribute.titleZero": "Don\'t assign any kittens as {0}",\n "ui.max.embassy.title": "Build {0} embassy for {1}",\n "ui.max.embassy.titleInfinite": "Never stop building embassies for {0}",\n "ui.max.embassy.titleZero": "Don\'t build embassies for {0}",\n "ui.max.prompt.absolute": "Enter the new limit as an absolute value between 0 and Infinity.",\n "ui.max.prompt.float": "Enter the new limit as an absolute value between 0.0 and Infinity.",\n "ui.max.set": "מירבי עבור {0}",\n "ui.max.timeSkip.prompt": "Enter the new amount of years as an absolute value between 0 and Infinity.",\n "ui.max.timeSkip.promptExplainer": "All notations that the game supports are accepted. If you submit an empty value, or a negative value, the limit will be set to infinity. If you set the limit to 0, this option will be automatically disabled. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.max.timeSkip.promptTitle": "Max. Years to skip (Current: {0})",\n "ui.max.timeSkip.title": "Skip {0} years at once",\n "ui.max.timeSkip.titleInfinite": "Skip as many years as possible",\n "ui.max.timeSkip.titleZero": "Don\'t skip time",\n "ui.maximum": "מירבי",\n "ui.min": "מינימלי: {0}",\n "ui.options": "אפשרויות",\n "ui.reset": "Reset list options to default configuration.",\n "ui.resources": "בקרת משאבים",\n "ui.space": "חלל",\n "ui.time": "זמן",\n "ui.timeCtrl": "שליטה בזמן",\n "ui.trade": "סחר",\n "ui.trigger": "מפעיל: {0}",\n "ui.trigger.accelerateTime.prompt": "Enter the new temporal flux storage level at which to enable Tempus Fugit as a percentage between 0.0 and 100.0.",\n "ui.trigger.accelerateTime.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.accelerateTime.promptTitle": "Trigger to Accelerate Time (Current: {0})",\n "ui.trigger.activeHeatTransfer.prompt": "Enter the new temporal heat storage level at which to enable heat transfer as a percentage between 0.0 and 100.0.",\n "ui.trigger.activeHeatTransfer.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.activeHeatTransfer.promptTitle": "Trigger for Heat Transfer (Current: {0})",\n "ui.trigger.build.blocked": "∞\\n🛈 The {0} section has no trigger set. This build will not be triggered!",\n "ui.trigger.build.inherited": "inherited from section",\n "ui.trigger.build.prompt": "Trigger for {0} (Current: {1})",\n "ui.trigger.build.promptExplainer": "If you submit an empty value, or a negative value, the section trigger is used instead. If you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.crypto.prompt": "Enter the new relic storage level at which to trade blackcoin as an absolute value between 0.0 and Infinity.",\n "ui.trigger.crypto.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.crypto.promptTitle": "Trigger to Trade Blackcoin (Current: {0})",\n "ui.trigger.embassies.prompt": "Enter the new culture storage level at which to build embassies as a percentage between 0.0 and 100.0.",\n "ui.trigger.embassies.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.embassies.promptTitle": "Trigger to Build Embassies (Current: {0})",\n "ui.trigger.hunt.prompt": "Trigger for Hunting (Current: {0})",\n "ui.trigger.hunt.promptExplainer": "If you submit a negative value, hunting will be disabled. If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.inactive": "inactive",\n "ui.trigger.promoteKittens.prompt": "Enter the new gold storage level at which to promote kittens as a percentage between 0.0 and 100.0.",\n "ui.trigger.promoteKittens.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.promoteKittens.promptTitle": "Trigger to Promote Kittens (Current: {0})",\n "ui.trigger.prompt.absolute": "Enter the new trigger value as an absolute value between 0 and Infinity.",\n "ui.trigger.prompt.float": "Enter the new trigger value as an absolute value between 0.0 and Infinity.",\n "ui.trigger.prompt.percentage": "Enter the new trigger value as a percentage between 0.0 and 100.0.",\n "ui.trigger.reset.promptExplainer": "If you submit a negative value, the item will be disabled. If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.section": "Section default trigger: {0}",\n "ui.trigger.section.blocked": "∞\\n🛈 The {0} section has no trigger set. This automation will not be triggered!",\n "ui.trigger.section.inactive": "∞ (nothing is triggered automatically)",\n "ui.trigger.section.inherited": "inherited from section",\n "ui.trigger.section.prompt": "Trigger for section {0} (Current: {1})",\n "ui.trigger.section.promptExplainer": "If you submit an empty value, or a negative value, the section trigger will be set to infinity (∞). Individual automations in this section need to have their own trigger set to be activated.\\nIf you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.setinteger": "Enter a new trigger value for {0}. Should be in the range from 0 up to any number. -1 means infinity.",\n "ui.trigger.setinteger.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.setpercentage": "Enter a new trigger value for {0}. Should be in the range from 0 to 100.",\n "ui.trigger.setpercentage.promptExplainer": "If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.timeSkip.prompt": "Enter the new amount of Time Crystals at which to skip time as an absolute value between 1 and Infinity.",\n "ui.trigger.timeSkip.promptExplainer": "If you submit a negative value, time skipping will be disabled. If you submit an empty value, or an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.timeSkip.promptTitle": "Trigger for Time Skip (Current: {0})",\n "ui.upgrade": "מדע",\n "ui.upgrade.buildings": "שדרג בניינים",\n "ui.upgrade.missions": "התחל משימות",\n "ui.upgrade.policies": "פוליסת מחקר",\n "ui.upgrade.races": "גלה גזעים חדשים",\n "ui.upgrade.techs": "חקור טכנולוגיות",\n "ui.upgrade.upgrades": "חקור שדרוגים",\n "ui.upgrades": "Upgrades",\n update: update$1,\n "upgrade.building.amphitheatre": "אמפיטאטראות שודרגו למגדלי שידור!",\n "upgrade.building.aqueduct": "אקוודוקטים שודרגו למפעלי מים!",\n "upgrade.building.library": "ספריות שודרגו למרכזיות מידע!",\n "upgrade.building.pasture": "אדמות חקלאיות שודרגו לשדות קולטני שמש!",\n "upgrade.building.warehouse": "Upgraded warehouses to spaceports!",\n "upgrade.policy": "חתלתולים העבירו {0}",\n "upgrade.race": "חתלתולים פגשו את {0}",\n "upgrade.space": "חתלתולים ביצעו {0}",\n "upgrade.space.mission": "חתלתולים ביצעו משימה אל {0}",\n "upgrade.tech": "חתלתולים קנו את הטכנולוגיה {0}",\n "upgrade.upgrade": "חתלתולים קנו את השדרוג {0}"\n };\n const copy = "复制";\n const reset = "重置";\n const update = "更新";\n const zhCN$1 = {\n "act.accelerate": "固有时制御,二倍速!",\n "act.adore": "赞美群星! 转化 {0} 虔诚为 {1} 顿悟",\n "act.blackcoin.buy": "小猫出售遗物并买入 {0} 黑币",\n "act.blackcoin.sell": "小猫出售黑币并买入了 {0} 遗物",\n "act.build": "小猫建造了一个 {0}",\n "act.builds": "小猫建造了 {1} 个新的 {0}",\n "act.craft": "小猫制作了 {0} {1}",\n "act.distribute": "分配一只猫猫成为 {0}",\n "act.elect": "小猫选出了一位新领导人",\n "act.feed": "小猫向上古神献上祭品。上古神很高兴",\n "act.fix.cry": "小猫修复了 {0} 个冷冻仓",\n "act.hunt": "派出 {0} 波小猫去打猎",\n "act.observe": "小猫珂学家观测到一颗流星",\n "act.praise": "赞美太阳! 转化 {0} 信仰为 {1} 虔诚",\n "act.promote": "领袖被提拔到 {0} 级",\n "act.refineTCs": "精炼 {0} 时间水晶",\n "act.refineTears": "将 {0} 泪水提炼成黑色眼泪",\n "act.sacrificeAlicorns": "献祭了 {0} 只天角兽",\n "act.sacrificeUnicorns": "已献祭的独角兽数:{0}",\n "act.sun.discover": "小猫在 {0} 方面获得顿悟",\n "act.sun.discovers": "小猫在 {0} 方面获得 {1} 次顿悟",\n "act.time.activeHeatTransferEnd": "主动散热完成",\n "act.time.activeHeatTransferStart": "开始主动散热",\n "act.time.getTemporalFlux": "烧水晶获取时间通量以维持时间加速",\n "act.time.skip": "燃烧时间水晶, 跳过接下来的 {0} 年!",\n "act.trade": "小猫与 {1} 交易 {0} 次",\n "act.transcend": "消耗 {0} 顿悟,达到超越 {1}",\n "blackcoin.buy": "买入单价:{0}",\n "blackcoin.buy.prompt": "输入您想要停止购买黑币的价格。",\n "blackcoin.buy.promptExplainer": "黑币价格总是从 800 上涨到 1100 (大致),然后暴跌。你通常应该一直买入直到卖出前不久。",\n "blackcoin.buy.promptTitle": "黑币购买限额 (当前:{0})",\n "blackcoin.buy.title": "购买黑币直至价格达到 {0}",\n "blackcoin.buy.trigger": "购买黑币(遗迹)",\n "blackcoin.sell": "卖出单价:{0}",\n "blackcoin.sell.prompt": "输入您想要出售所有黑币的价格。",\n "blackcoin.sell.promptExplainer": "黑币价格总是从 800 上涨到 1100 (大致),然后暴跌。你通常希望以接近最高价的价格出售。",\n "blackcoin.sell.promptTitle": "黑币卖单 (当前:{0})",\n "blackcoin.sell.title": "当价格达到 {0} 时出售黑币",\n "build.embassies": "在 {1} 设立了 {0} 个大使馆",\n "build.embassy": "在 {1} 设立了 {0} 个大使馆",\n copy,\n "craft.limited": "制作 {0} 受库存消耗比率的限制",\n "craft.unlimited": "制作 {0} 不受限制",\n "delete": "删除",\n "dispose.necrocorn": "小猫处理掉了影响效率的多余死灵兽",\n "festival.extend": "小猫延长了节日",\n "festival.hold": "小猫开始举办节日",\n "filter.accelerate": "时间加速",\n "filter.adore": "赞美群星",\n "filter.allKG": "所有游戏日志",\n "filter.build": "建筑",\n "filter.craft": "工艺",\n "filter.disable": "过滤 {0} 日志消息",\n "filter.distribute": "猫口分配",\n "filter.enable": "启用 {0} 日志消息",\n "filter.explainer": "已禁用的项目不会显示在日志中。",\n "filter.faith": "太阳秩序",\n "filter.festival": "节日",\n "filter.hunt": "狩猎",\n "filter.misc": "杂项",\n "filter.praise": "赞美太阳",\n "filter.promote": "提拔领袖",\n "filter.research": "研究",\n "filter.star": "天文事件",\n "filter.timeSkip": "时间跳转",\n "filter.trade": "贸易",\n "filter.transcend": "超越",\n "filter.upgrade": "升级",\n "option.accelerate": "时间加速",\n "option.autofeed": "献祭上古神",\n "option.catnip": "采集猫薄荷",\n "option.crypto": "黑币交易",\n "option.elect": "选择领导人",\n "option.elect.job": "工作",\n "option.elect.job.any": "任何",\n "option.elect.trait": "特质",\n "option.embassies": "建造大使馆",\n "option.faith.adore": "赞美群星",\n "option.faith.autoPraise": "赞美太阳",\n "option.faith.best.unicorn": "优先最佳独角兽建筑",\n "option.faith.refineTears": "提炼眼泪",\n "option.faith.refineTimeCrystals": "精炼时间水晶",\n "option.faith.sacrificeAlicorns": "献祭天角兽",\n "option.faith.sacrificeUnicorns": "献祭独角兽",\n "option.faith.transcend": "自动超越",\n "option.festival": "举办节日",\n "option.fix.cry": "修复冷冻仓",\n "option.hunt": "狩猎",\n "option.magnetos": "开启磁电机",\n "option.observe": "观测天文事件",\n "option.praise": "赞美太阳",\n "option.promote": "提拔领袖",\n "option.promotekittens": "提拔小猫",\n "option.reactors": "开启反应堆",\n "option.shipOverride": "强制243船",\n "option.steamworks": "启动蒸汽工房",\n "option.time.activeHeatTransfer": "主动散热",\n "option.time.reset": "重启时间线 (危险!)",\n "option.time.skip": "时间跳转",\n "option.time.skip.ignoreOverheat": "忽略过热",\n reset,\n "reset.after": "初次见面,可爱的猫猫科学家为您服务",\n "reset.cancel.activity": "喵斯顿,我们有麻烦了",\n "reset.cancel.message": "重启时间线计划取消",\n "reset.check": "{0} 的触发值: {1}, 现在共有 {2}",\n "reset.checked": "所有条件都已满足,时间线将在几秒后重启!",\n "reset.countdown.0": " 0 - 时空裂缝已打开!",\n "reset.countdown.1": " 1 - 时间引擎已启动!",\n "reset.countdown.2": " 2 - 正在启动时间锻造",\n "reset.countdown.3": " 3 - 正在打开时空裂隙",\n "reset.countdown.4": " 4 - 正在关闭卫星",\n "reset.countdown.5": " 5 - 正在融化黑币",\n "reset.countdown.6": " 6 - 正在启动时间引擎",\n "reset.countdown.7": " 7 - 正在拆解电磁炮",\n "reset.countdown.8": " 8 - 正在放生蜥蜴",\n "reset.countdown.9": " 9 - 正在献祭独角兽",\n "reset.countdown.10": " 10 - 正在收获猫薄荷",\n "reset.last.message": "我们下个庞加莱回归再见",\n "reset.tip": "您可以通过在设置顶部禁用“启用小猫珂学家”选项来取消此重置。",\n "resources.consume": "消耗率: {0}",\n "resources.consume.prompt": "输入您希望自动化消耗的资源量,以 0.0 到 100.0 之间的百分比表示。",\n "resources.consume.promptExplainer": "如果您提交一个空值或者一个无效值,则被视为您点击了取消。",\n "resources.consume.promptTitle": "{0} 的消耗份额 (当前:{1})",\n "resources.consume.set": "设置 {0} 的消耗率",\n "resources.consume.title": "消耗 {0} 的 {1}",\n "resources.consume.titleZero": "不消耗 {0}",\n "resources.stock.prompt": "输入您希望始终保留的资源库存量。",\n "resources.stock.promptExplainer": "游戏支持的所有符号均可接受。如果您提交空值或负值,限制将设置为无穷大。如果您将限制设置为 0,此选项将自动禁用。如果您提交无效值,将被视为您点击了“取消”。",\n "resources.stock.promptTitle": "{0} 的库存值 (当前:{1})",\n "resources.stock.title": "保持 {0} {1} 库存",\n "resources.stock.titleInfinite": "保持所有 {0} 库存",\n "resources.stock.titleZero": "不保留任何 {0} 库存",\n "state.compress": "压缩数据",\n "state.confirmDestruction": "你确定吗?",\n "state.copied.game": "保存“{0}”复制到剪贴板。",\n "state.copied.gameCurrent": "当前保存已复制到剪贴板。",\n "state.copied.state": "状态“{0}”已复制到剪贴板。",\n "state.copied.stateCurrent": "当前状态已复制到剪贴板。",\n "state.copy.game": "将此保存复制到剪贴板。",\n "state.copy.gameCurrent": "将整个小猫游戏保存 (包括 KS 设置) 复制到剪贴板。",\n "state.copy.state": "将这些设置复制到剪贴板。",\n "state.copy.stateCurrent": "将当前的 Kitten Scientists 设置复制到剪贴板。",\n "state.delete.game": "删除此保存。",\n "state.delete.state": "删除这些设置。",\n "state.deleted.game": "保存“{0}”已删除。",\n "state.deleted.state": "状态“{0}”已删除。",\n "state.edit.game": "更改此保存的名称。",\n "state.edit.state": "更改这些设置的名称。",\n "state.exportAll": "备份",\n "state.exportAllTitle": "将所有本地状态存储在单个文件中并下载。",\n "state.import": "从剪贴板导入",\n "state.imported.game": "保存导入。",\n "state.imported.state": "状态导入。",\n "state.importedState": "Imported state {0}",\n "state.importTitle": "从剪贴板粘贴保存或设置。\\n内容将被自动检测并进行相应处理。",\n "state.loaded.game": "已加载保存“{0}”。",\n "state.loaded.state": "已加载状态“{0}”。",\n "state.loadPrompt": "在此处粘贴您的 (未压缩的) 保存或设置:",\n "state.local": "本地状态",\n "state.localGames": "小猫游戏保存",\n "state.localStates": "小猫科学家设置",\n "state.new": "新的",\n "state.noConfirm": "不要求确认",\n "state.store": "储存",\n "state.stored.game": "保存储存。",\n "state.stored.state": "状态储存。",\n "state.storeFactory": "根据出厂默认设置创建新状态。",\n "state.storeGame": "从当前游戏中创建一个新的保存。",\n "state.storeGame.prompt": "为此次保存提供标签:",\n "state.storeState": "根据当前设置创建一个新状态。",\n "state.storeState.prompt": "为该状态提供标签:",\n "state.title": "状态管理器",\n "state.unlabeledGame": "未标记的保存",\n "state.unlabeledState": "未标记状态",\n "state.update.game": "将当前游戏保存到此位置。",\n "state.update.state": "将当前设置保存到此槽中。",\n "state.updated.game": "保存\'{0}\'已更新。",\n "state.updated.state": "状态“{0}”已更新。",\n "status.auto.disable": "禁用自动化 {0}",\n "status.auto.enable": "启用自动化 {0}",\n "status.ks.disable": "太敬业了,该歇了",\n "status.ks.enable": "神说,要有猫猫珂学家!",\n "status.ks.init": "小猫珂学家已初始化。",\n "status.ks.upgrade": "小猫珂学家 (当前版本:{1}) {0} 可在这里获取:{2} 。",\n "status.reset.check.disable": "在重启时间线前不检查 {0}",\n "status.reset.check.enable": "在重启时间线前检查 {0}",\n "status.resource.disable": "禁用 {0} 资源管理",\n "status.resource.enable": "启用 {0} 资源管理",\n "status.sub.disable": "禁用 {0}",\n "status.sub.enable": "启用 {0}",\n "summary.accelerate": "加速时间 {0} 次",\n "summary.adore": "通过赞美群星积累了 {0} 顿悟",\n "summary.building": "建造了 {0} 个 {1}",\n "summary.craft": "制作了 {0} 个 {1}",\n "summary.day": "天",\n "summary.days": "天",\n "summary.distribute": "帮助 {0} 只猫猫找到工作",\n "summary.embassy": "设立了 {0} 个大使馆",\n "summary.feed": "向上古神献祭 {0} 只死灵兽",\n "summary.festival": "举办了 {0} 次节日",\n "summary.fix.cry": "修复了 {0} 个冷冻仓",\n "summary.head": "过去 {0} 的总结",\n "summary.hunt": "派出了 {0} 批可爱的小猫猎人",\n "summary.praise": "通过赞美太阳积累了 {0} 虔诚",\n "summary.promote": "提拔领袖 {0} 次",\n "summary.refine": "已精炼 {0} {1}",\n "summary.separator": " ",\n "summary.show": "总结",\n "summary.stars": "观测了 {0} 颗流星",\n "summary.sun": "在 {1} 方面顿悟 {0} 次",\n "summary.tech": "掌握了 {0}",\n "summary.time.activeHeatTransferStart": "主动散热 {0} 次",\n "summary.time.getTemporalFlux": "烧水晶获取时间通量 {0} 次",\n "summary.time.reset.content": "获得 {0} 业.<br>获得 {1} 领导力",\n "summary.time.reset.title": "过去 {0} 个时间线的总结",\n "summary.time.skip": "跳过 {0} 年",\n "summary.trade": "与 {1} 贸易了 {0} 次",\n "summary.transcend": "超越了 {0} 次",\n "summary.upgrade": "发明了 {0}",\n "summary.year": "年",\n "summary.years": "年",\n "time.heatTransfer.cycle.disable": "停止在 {0} 主动散热",\n "time.heatTransfer.cycle.enable": "启用在 {0} 主动散热",\n "time.skip.cycle.disable": "停止在 {0} 跳转时间并禁止跳过该周期",\n "time.skip.cycle.enable": "启用在 {0} 跳转时间并允许跳过该周期",\n "time.skip.season.disable": "停止在 {0} 跳转时间",\n "time.skip.season.enable": "启用在 {0} 跳转时间",\n "trade.limited": "与 {0} 的交易限制为比产量更优时才会触发",\n "trade.season.disable": "停止在 {1} 与 {0} 的交易",\n "trade.season.enable": "启用在 {1} 与 {0} 的交易",\n "trade.seasons": "季节",\n "trade.unlimited": "取消与 {0} 交易的限制",\n "ui.additional": "附加选项",\n "ui.build": "营火",\n "ui.close": "关闭",\n "ui.craft": "工艺",\n "ui.craft.resources": "资源",\n "ui.cycles": "周期",\n "ui.disable.all": "全部禁用",\n "ui.distribute": "猫力资源",\n "ui.enable.all": "全部启用",\n "ui.engine": "启用小猫珂学家",\n "ui.faith": "宗教",\n "ui.filter": "日志过滤",\n "ui.infinity": "∞",\n "ui.internals": "小喵设置",\n "ui.internals.interval": "运行间隔(ms): {0}",\n "ui.internals.interval.prompt": "输入新的毫秒数作为 0 到无穷大之间的绝对值。",\n "ui.internals.interval.promptExplainer": "游戏支持的所有符号均可接受。如果您将限制设置为 0,Kitten Scientists 将自动禁用。如果您提交了无效值,则将被视为您点击了“取消”。",\n "ui.internals.interval.promptTitle": "小猫科学家执行间隔 (当前:{0})",\n "ui.itemsHide": "隐藏选项",\n "ui.itemsShow": "显示选项",\n "ui.ksColumn": "显示在第四栏",\n "ui.language": "语言",\n "ui.limit": "限制",\n "ui.limited.off": "无限",\n "ui.limited.on": "环保模式",\n "ui.max": "最大值:{0}",\n "ui.max.build.prompt": "{0} 的限制 (当前:{1})",\n "ui.max.build.promptExplainer": "游戏支持的所有符号均可接受。如果您提交空值或负值,限制将设置为无穷大。如果您将限制设置为 0,此选项将自动禁用。如果您提交无效值,将被视为您点击了“取消”。",\n "ui.max.build.title": "构建 {0} {1}",\n "ui.max.build.titleInfinite": "永不停止建设{0}",\n "ui.max.build.titleZero": "不要构建{0}",\n "ui.max.craft.prompt": "输入要制作的 {0} 数量的新限制,以 0 到无穷大之间的绝对值表示。",\n "ui.max.craft.promptExplainer": "游戏支持的所有符号均可接受。如果您提交空值或负值,限制将设置为无穷大。如果您将限制设置为 0,此选项将自动禁用。如果您提交无效值,将被视为您点击了“取消”。",\n "ui.max.craft.promptTitle": "制作限制 {0} (当前:{1})",\n "ui.max.craft.title": "制造 {0} {1}",\n "ui.max.craft.titleInfinite": "永不停止创造{0}",\n "ui.max.craft.titleZero": "不要制造 {0}",\n "ui.max.distribute.prompt": "输入要分配的新小猫数量 {0},作为 0 到无穷大之间的绝对值。",\n "ui.max.distribute.promptExplainer": "游戏支持的所有符号均可接受。如果您提交空值或负值,限制将设置为无穷大。如果您将限制设置为 0,此选项将自动禁用。如果您提交无效值,将被视为您点击了“取消”。",\n "ui.max.distribute.promptTitle": "将最大小猫数量指定为 {0} (当前:{1})",\n "ui.max.distribute.title": "将 {0} 只小猫指定为 {1}",\n "ui.max.distribute.titleInfinite": "分配尽可能多的小猫作为{0}",\n "ui.max.distribute.titleZero": "不将任何小猫指定为{0}",\n "ui.max.embassy.title": "为{1}建造{0}大使馆",\n "ui.max.embassy.titleInfinite": "永不停止为{0}修建大使馆",\n "ui.max.embassy.titleZero": "不要为{0}建造大使馆",\n "ui.max.prompt.absolute": "输入新的限制作为 0 到无穷大之间的绝对值。",\n "ui.max.prompt.float": "输入新的限制作为 0.0 和无穷大之间的绝对值。",\n "ui.max.set": "设置 {0} 的最大值",\n "ui.max.timeSkip.prompt": "输入新的年数作为 0 至无穷大之间的绝对值。",\n "ui.max.timeSkip.promptExplainer": "游戏支持的所有符号均可接受。如果您提交空值或负值,限制将设置为无穷大。如果您将限制设置为 0,此选项将自动禁用。如果您提交无效值,将被视为您点击了“取消”。",\n "ui.max.timeSkip.promptTitle": "最多跳过年份 (当前:{0})",\n "ui.max.timeSkip.title": "一次跳过 {0} 年",\n "ui.max.timeSkip.titleInfinite": "跳过尽可能多的年份",\n "ui.max.timeSkip.titleZero": "不要跳过时间",\n "ui.maximum": "上限",\n "ui.min": "最小值 {0}",\n "ui.options": "选项",\n "ui.reset": "恢复至默认",\n "ui.resources": "资源控制",\n "ui.space": "太空",\n "ui.time": "时间",\n "ui.timeCtrl": "时间操纵",\n "ui.trade": "贸易",\n "ui.trigger": "触发值:{0}",\n "ui.trigger.accelerateTime.prompt": "输入启用 Tempus Fugit 的新时间通量存储级别,以 0.0 至 100.0 之间的百分比表示。",\n "ui.trigger.accelerateTime.promptExplainer": "如果您提交一个空值或者一个无效值,则被视为您点击了取消。",\n "ui.trigger.accelerateTime.promptTitle": "加速时间的触发值 (当前:{0})",\n "ui.trigger.activeHeatTransfer.prompt": "输入新的启用热传递的时间热存储量,以 0.0 到 100.0 之间的百分比表示。",\n "ui.trigger.activeHeatTransfer.promptExplainer": "如果您提交一个空值或者一个无效值,则被视为您点击了取消。",\n "ui.trigger.activeHeatTransfer.promptTitle": "热传递触发值 (当前:{0})",\n "ui.trigger.build.blocked": "∞\\n🛈 {0} 部分未设置触发值。此构建不会被触发!",\n "ui.trigger.build.inherited": "继承自部分",\n "ui.trigger.build.prompt": "{0} 的触发值 (当前:{1})",\n "ui.trigger.build.promptExplainer": "如果您提交了空值或负值,则将使用部分触发值。如果您提交了无效值,则将被视为您点击了“取消”。",\n "ui.trigger.crypto.prompt": "输入交易黑币的新文物存储级别,以 0.0 到 Infinity 之间的绝对值表示。",\n "ui.trigger.crypto.promptExplainer": "如果您提交一个空值或者一个无效值,则被视为您点击了取消。",\n "ui.trigger.crypto.promptTitle": "触发黑币交易 (当前:{0})",\n "ui.trigger.embassies.prompt": "以 0.0 至 100.0 之间的百分比输入建造大使馆的新文化存储级别。",\n "ui.trigger.embassies.promptExplainer": "如果您提交一个空值或者一个无效值,则被视为您点击了取消。",\n "ui.trigger.embassies.promptTitle": "建立大使馆的触发值 (当前:{0})",\n "ui.trigger.hunt.prompt": "狩猎触发值 (当前:{0})",\n "ui.trigger.hunt.promptExplainer": "如果您提交了负值,则搜索将被禁用。如果您提交了空值或无效值,则将被视为您点击了“取消”。",\n "ui.trigger.inactive": "不活跃",\n "ui.trigger.promoteKittens.prompt": "输入新的可用于升级小猫的黄金库存量,以 0.0 到 100.0 之间的百分比表示。",\n "ui.trigger.promoteKittens.promptExplainer": "如果您提交一个空值或者一个无效值,则被视为您点击了取消。",\n "ui.trigger.promoteKittens.promptTitle": "小猫促销触发值 (当前:{0})",\n "ui.trigger.prompt.absolute": "输入新的触发值作为 0 到无穷大之间的绝对值。",\n "ui.trigger.prompt.float": "输入新的触发值作为 0.0 到无穷大之间的绝对值。",\n "ui.trigger.prompt.percentage": "以 0.0 至 100.0 之间的百分比形式输入新的触发值。",\n "ui.trigger.reset.promptExplainer": "如果您提交了负值,则该项目将被禁用。如果您提交了空值或无效值,则将被视为您点击了“取消”。",\n "ui.trigger.section": "部分默认触发值:{0}",\n "ui.trigger.section.blocked": "∞\\n🛈 The {0} section has no trigger set. This automation will not be triggered!",\n "ui.trigger.section.inactive": "∞ (nothing is triggered automatically)",\n "ui.trigger.section.inherited": "继承自部分",\n "ui.trigger.section.prompt": "{0} 部分的触发值 (当前:{1})",\n "ui.trigger.section.promptExplainer": "If you submit an empty value, or a negative value, the section trigger will be set to infinity (∞). Individual automations in this section need to have their own trigger set to be activated.\\nIf you submit an invalid value, it will be treated as if you hit Cancel.",\n "ui.trigger.setinteger": "输入 {0} 的新触发值。范围应在 0 到任意数字之间。-1表示无穷大。",\n "ui.trigger.setinteger.promptExplainer": "如果您提交一个空值或者一个无效值,则被视为您点击了取消。",\n "ui.trigger.setpercentage": "输入新的 {0} 触发值,取值范围为 0 到 100 的小数。",\n "ui.trigger.setpercentage.promptExplainer": "如果您提交一个空值或者一个无效值,则被视为您点击了取消。",\n "ui.trigger.timeSkip.prompt": "输入跳过时间所需的时间水晶的新数量,以 1 到无穷大之间的绝对值表示。",\n "ui.trigger.timeSkip.promptExplainer": "如果您提交了负值,时间跳过将被禁用。如果您提交了空值或无效值,它将被视为您点击了“取消”。",\n "ui.trigger.timeSkip.promptTitle": "时间跳跃触发值 (当前:{0})",\n "ui.upgrade": "升级",\n "ui.upgrade.buildings": "升级建筑",\n "ui.upgrade.missions": "探索星球",\n "ui.upgrade.policies": "政策",\n "ui.upgrade.races": "探险队出发!",\n "ui.upgrade.techs": "科技",\n "ui.upgrade.upgrades": "升级",\n "ui.upgrades": "升级",\n update,\n "upgrade.building.amphitheatre": "剧场 升级为 广播塔!",\n "upgrade.building.aqueduct": "水渠 升级为 水电站!",\n "upgrade.building.library": "图书馆 升级为 数据中心!",\n "upgrade.building.pasture": "牧场 升级为 太阳能发电站!",\n "upgrade.building.warehouse": "已将仓库升级为太空港!",\n "upgrade.policy": "小猫通过了 {0} 法案",\n "upgrade.race": "小猫遇到了 {0}",\n "upgrade.space": "小猫执行了 {0}",\n "upgrade.space.mission": "小猫执行了 {0} 的任务",\n "upgrade.tech": "小猫掌握了 {0}",\n "upgrade.upgrade": "小猫发明了 {0}"\n };\n class ReligionSettingsItem extends SettingTriggerMax {\n constructor(building, variant, enabled = false) {\n super(enabled);\n __privateAdd(this, _building2);\n __privateAdd(this, _variant);\n __privateSet(this, _building2, building);\n __privateSet(this, _variant, variant);\n }\n get building() {\n return __privateGet(this, _building2);\n }\n get variant() {\n return __privateGet(this, _variant);\n }\n }\n _building2 = new WeakMap();\n _variant = new WeakMap();\n class ReligionSettings extends SettingTrigger {\n constructor(enabled = false, trigger = -1, bestUnicornBuilding = new Setting(), sacrificeAlicorns = new SettingThreshold(false, -1), sacrificeUnicorns = new SettingThreshold(false, -1), refineTears = new SettingThreshold(false, -1), refineTimeCrystals = new SettingThreshold(false, -1), autoPraise = new SettingTrigger(false, 1), adore = new SettingTrigger(false, 1), transcend = new Setting()) {\n super(enabled, trigger);\n __publicField(this, "buildings");\n /**\n * Build best unicorn building first.\n */\n __publicField(this, "bestUnicornBuilding");\n __publicField(this, "bestUnicornBuildingCurrent");\n /**\n * Sacrifice alicorns for time crystals.\n */\n __publicField(this, "sacrificeAlicorns");\n /**\n * Sacrifice unicorns for tears.\n */\n __publicField(this, "sacrificeUnicorns");\n /**\n * Refine tears into BLS.\n */\n __publicField(this, "refineTears");\n /**\n * Refine time crystals into relics.\n */\n __publicField(this, "refineTimeCrystals");\n /**\n * Praise the sun.\n */\n __publicField(this, "autoPraise");\n /**\n * Adore the galaxy.\n */\n __publicField(this, "adore");\n /**\n * Transcend.\n */\n __publicField(this, "transcend");\n this.buildings = this.initBuildings();\n this.bestUnicornBuilding = bestUnicornBuilding;\n this.sacrificeAlicorns = sacrificeAlicorns;\n this.sacrificeUnicorns = sacrificeUnicorns;\n this.refineTears = refineTears;\n this.refineTimeCrystals = refineTimeCrystals;\n this.autoPraise = autoPraise;\n this.adore = adore;\n this.transcend = transcend;\n this.bestUnicornBuildingCurrent = null;\n }\n initBuildings() {\n const items = {};\n for (const item of ReligionUpgrades) {\n items[item] = new ReligionSettingsItem(item, UnicornItemVariant.OrderOfTheSun);\n }\n for (const item of TranscendenceUpgrades) {\n items[item] = new ReligionSettingsItem(item, UnicornItemVariant.Cryptotheology);\n }\n for (const item of ZigguratUpgrades) {\n items[item] = new ReligionSettingsItem(item, UnicornItemVariant.Ziggurat);\n }\n items.unicornPasture = new ReligionSettingsItem(\n "unicornPasture",\n UnicornItemVariant.UnicornPasture\n );\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n building.max = (item == null ? void 0 : item.max) ?? building.max;\n building.trigger = (item == null ? void 0 : item.trigger) ?? building.trigger;\n });\n this.bestUnicornBuilding.load(settings.bestUnicornBuilding);\n this.sacrificeAlicorns.load(settings.sacrificeAlicorns);\n this.sacrificeUnicorns.load(settings.sacrificeUnicorns);\n this.refineTears.load(settings.refineTears);\n this.refineTimeCrystals.load(settings.refineTimeCrystals);\n this.autoPraise.load(settings.autoPraise);\n this.adore.load(settings.adore);\n this.transcend.load(settings.transcend);\n this.bestUnicornBuildingCurrent = settings.bestUnicornBuildingCurrent ?? this.bestUnicornBuildingCurrent;\n }\n }\n class ReligionManager {\n constructor(host, bonfireManager, workshopManager, settings = new ReligionSettings()) {\n __publicField(this, "_host");\n __publicField(this, "settings");\n __publicField(this, "manager");\n __publicField(this, "_bulkManager");\n __publicField(this, "_bonfireManager");\n __publicField(this, "_workshopManager");\n this._host = host;\n this.settings = settings;\n this.manager = new TabManager(this._host, "Religion");\n this._workshopManager = workshopManager;\n this._bulkManager = new BulkPurchaseHelper(this._host, this._workshopManager);\n this._bonfireManager = bonfireManager;\n }\n async tick(context) {\n if (!this.settings.enabled) {\n return;\n }\n this.manager.render();\n this._autoBuild(context);\n if (this.settings.sacrificeUnicorns.enabled) {\n await this._autoSacrificeUnicorns();\n }\n if (this.settings.sacrificeAlicorns.enabled) {\n await this._autoSacrificeAlicorns(context);\n }\n if (this.settings.refineTears.enabled) {\n this._autoTears(context);\n }\n if (this.settings.refineTimeCrystals.enabled) {\n await this._autoTCs(context);\n }\n this._autoTAP();\n }\n _autoBuild(context) {\n if (this.settings.bestUnicornBuilding.enabled) {\n this._buildBestUnicornBuilding();\n this._buildNonUnicornBuildings(context);\n } else {\n const builds = Object.fromEntries(\n Object.entries(this.settings.buildings).filter(\n ([, building]) => building.variant !== UnicornItemVariant.UnicornPasture\n )\n );\n const maxPastures = negativeOneToInfinity(this.settings.buildings.unicornPasture.max);\n const meta = this._host.game.bld.getBuildingExt("unicornPasture").meta;\n if (this.settings.buildings.unicornPasture.enabled && meta.val < maxPastures) {\n this._bonfireManager.autoBuild(context, {\n unicornPasture: new BonfireBuildingSetting(\n "unicornPasture",\n this.settings.buildings.unicornPasture.enabled,\n this.settings.buildings.unicornPasture.trigger,\n this.settings.buildings.unicornPasture.max\n )\n });\n }\n this._buildReligionBuildings(context, builds);\n }\n }\n _buildBestUnicornBuilding() {\n var _a, _b;\n const bestUnicornBuilding = this.getBestUnicornBuilding();\n if (this.settings.bestUnicornBuildingCurrent !== bestUnicornBuilding) {\n this.settings.bestUnicornBuildingCurrent = bestUnicornBuilding;\n this._host.refreshEntireUserInterface();\n }\n if (this.settings.bestUnicornBuildingCurrent === null) {\n return;\n }\n const sectionTrigger = this.settings.trigger;\n if (this.settings.bestUnicornBuildingCurrent === "unicornPasture") {\n this._bonfireManager.build(this.settings.bestUnicornBuildingCurrent, 0, 1);\n } else {\n const buildingButton = this._getBuildButton(\n this.settings.bestUnicornBuildingCurrent,\n UnicornItemVariant.Ziggurat\n );\n if (isNil(buildingButton == null ? void 0 : buildingButton.model)) {\n return;\n }\n let tearsNeeded = 0;\n const priceTears = mustExist(buildingButton.model.prices).find(\n (subject) => subject.name === "tears"\n );\n if (!isNil(priceTears)) {\n tearsNeeded = priceTears.val;\n }\n const tearsAvailableForUse = this._workshopManager.getValue("tears") - this._workshopManager.getStock("tears");\n if (!isNil(this._host.game.religionTab.sacrificeBtn) && tearsAvailableForUse < tearsNeeded) {\n const maxSacrifice = Math.floor(\n (this._workshopManager.getValue("unicorns") - this._workshopManager.getStock("unicorns")) / 2500\n );\n const needSacrifice = Math.ceil(\n (tearsNeeded - tearsAvailableForUse) / this._host.game.bld.getBuildingExt("ziggurat").meta.on\n );\n if (needSacrifice < maxSacrifice && !isNil(this._host.game.religionTab.sacrificeBtn.model)) {\n (_b = (_a = this._host.game.religionTab.sacrificeBtn) == null ? void 0 : _a.controller) == null ? void 0 : _b._transform(\n this._host.game.religionTab.sacrificeBtn.model,\n needSacrifice\n );\n } else {\n return;\n }\n }\n const buildRequest = {\n [this.settings.bestUnicornBuildingCurrent]: this.settings.buildings[this.settings.bestUnicornBuildingCurrent]\n };\n const build = this._bulkManager.bulk(\n buildRequest,\n this.getBuildMetaData(buildRequest),\n sectionTrigger,\n "Religion"\n );\n if (0 < build.length && 0 < build[0].count) {\n this.build(this.settings.bestUnicornBuildingCurrent, UnicornItemVariant.Ziggurat, 1);\n }\n }\n }\n _buildNonUnicornBuildings(context) {\n const alreadyHandled = [...UnicornItems];\n const builds = Object.fromEntries(\n Object.entries(this.settings.buildings).filter(\n ([, building]) => !alreadyHandled.includes(building.building)\n )\n );\n this._buildReligionBuildings(context, builds);\n }\n _buildReligionBuildings(context, builds) {\n this.manager.render();\n const metaData = this.getBuildMetaData(builds);\n const sectionTrigger = this.settings.trigger;\n const buildList = this._bulkManager.bulk(builds, metaData, sectionTrigger, "Religion");\n for (const build of buildList) {\n if (0 < build.count) {\n this.build(\n build.id,\n mustExist(build.variant),\n build.count\n );\n context.requestGameUiRefresh = true;\n }\n }\n }\n /**\n * Determine the best unicorn-related building to buy next.\n * This is the building where the cost is in the best proportion to the\n * unicorn production bonus it generates.\n *\n * @see https://github.com/Bioniclegenius/NummonCalc/blob/112f716e2fde9956dfe520021b0400cba7b7113e/NummonCalc.js#L490\n * @returns The best unicorn building.\n */\n getBestUnicornBuilding() {\n var _a, _b;\n const pastureButton = this._bonfireManager.getBuildButton("unicornPasture");\n if (pastureButton === null) {\n return null;\n }\n const validBuildings = [...UnicornItems].filter(\n (item) => item !== "unicornPasture"\n );\n const unicornsPerSecondBase = this._host.game.getEffect("unicornsPerTickBase") * this._host.game.getTicksPerSecondUI();\n const globalRatio = this._host.game.getEffect("unicornsGlobalRatio") + 1;\n const religionRatio = this._host.game.getEffect("unicornsRatioReligion") + 1;\n const paragonRatio = this._host.game.prestige.getParagonProductionRatio() + 1;\n const faithBonus = this._host.game.religion.getSolarRevolutionRatio() + 1;\n const currentCycleIndex = this._host.game.calendar.cycle;\n const currentCycle = this._host.game.calendar.cycles[currentCycleIndex];\n let cycleBonus = 1;\n if (currentCycle.festivalEffects.unicorns !== void 0) {\n if (this._host.game.prestige.getPerk("numeromancy").researched && this._host.game.calendar.festivalDays) {\n cycleBonus = currentCycle.festivalEffects.unicorns;\n }\n }\n const unicornsPerSecond = unicornsPerSecondBase * globalRatio * religionRatio * paragonRatio * faithBonus * cycleBonus;\n const zigguratRatio = Math.max(this._host.game.bld.getBuildingExt("ziggurat").meta.on, 1);\n const baseUnicornsPerRift = 500 * (1 + this._host.game.getEffect("unicornsRatioReligion") * 0.1);\n let riftChanceRatio = 1;\n if (this._host.game.prestige.getPerk("unicornmancy").researched) {\n riftChanceRatio *= 1.1;\n }\n const unicornRiftChange = this._host.game.getEffect("riftChance") * riftChanceRatio / (1e4 * 2) * baseUnicornsPerRift;\n let bestAmortization = Number.POSITIVE_INFINITY;\n let bestBuilding = null;\n const unicornsPerTickBase = mustExist(\n (_a = this._host.game.bld.getBuildingExt("unicornPasture").meta.effects) == null ? void 0 : _a.unicornsPerTickBase\n );\n const pastureProduction = unicornsPerTickBase * this._host.game.getTicksPerSecondUI() * globalRatio * religionRatio * paragonRatio * faithBonus * cycleBonus;\n const pastureAmortization = mustExist((_b = pastureButton.model) == null ? void 0 : _b.prices)[0].val / pastureProduction;\n if (pastureAmortization < bestAmortization) {\n bestAmortization = pastureAmortization;\n bestBuilding = "unicornPasture";\n }\n for (const button2 of this.manager.tab.zgUpgradeButtons) {\n if (validBuildings.includes(button2.id) && button2.model.visible) {\n let unicornPrice = 0;\n for (const price of mustExist(button2.model.prices)) {\n if (price.name === "unicorns") {\n unicornPrice += price.val;\n }\n if (price.name === "tears") {\n unicornPrice += price.val * 2500 / zigguratRatio;\n }\n }\n const buildingInfo = mustExist(this._host.game.religion.getZU(button2.id));\n let religionBonus = religionRatio;\n let riftChance = this._host.game.getEffect("riftChance");\n for (const effect in buildingInfo.effects) {\n if (effect === "unicornsRatioReligion") {\n religionBonus += mustExist(buildingInfo.effects.unicornsRatioReligion);\n }\n if (effect === "riftChance") {\n riftChance += mustExist(buildingInfo.effects.riftChance);\n }\n }\n const unicornsPerRift = 500 * ((religionBonus - 1) * 0.1 + 1);\n let riftBonus = riftChance * riftChanceRatio / (1e4 * 2) * unicornsPerRift;\n riftBonus -= unicornRiftChange;\n let buildingProduction = unicornsPerSecondBase * globalRatio * religionBonus * paragonRatio * faithBonus * cycleBonus;\n buildingProduction -= unicornsPerSecond;\n buildingProduction += riftBonus;\n const amortization = unicornPrice / buildingProduction;\n if (amortization < bestAmortization) {\n if (0 < riftBonus || religionRatio < religionBonus && 0 < unicornPrice) {\n bestAmortization = amortization;\n bestBuilding = button2.id;\n }\n }\n }\n }\n return bestBuilding;\n }\n build(name, variant, amount) {\n let amountCalculated = amount;\n const amountTemp = amountCalculated;\n let label2;\n if (variant === UnicornItemVariant.Cryptotheology) {\n const itemMetaRaw = game.getUnlockByName(name, "transcendenceUpgrades");\n const controller = new classes.ui.TranscendenceBtnController(\n this._host.game\n );\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);\n label2 = itemMetaRaw.label;\n } else if (variant === UnicornItemVariant.OrderOfTheSun) {\n const itemMetaRaw = game.getUnlockByName(name, "religion");\n const controller = new com.nuclearunicorn.game.ui.ReligionBtnController(\n this._host.game\n );\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);\n label2 = itemMetaRaw.label;\n } else if (variant === UnicornItemVariant.Ziggurat) {\n const itemMetaRaw = game.getUnlockByName(name, "zigguratUpgrades");\n const controller = new com.nuclearunicorn.game.ui.ZigguratBtnController(\n this._host.game\n );\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);\n label2 = itemMetaRaw.label;\n } else {\n throw new InvalidOperationError("unsupported");\n }\n if (amountCalculated !== amountTemp) {\n console.warn(\n ...cl(`${label2} Amount ordered: ${amountTemp} Amount Constructed: ${amountCalculated}`)\n );\n if (amountCalculated === 0) {\n return;\n }\n }\n if (variant === UnicornItemVariant.OrderOfTheSun) {\n this._host.engine.storeForSummary(label2, amountCalculated, "faith");\n if (amountCalculated === 1) {\n this._host.engine.iactivity("act.sun.discover", [label2], "ks-faith");\n } else {\n this._host.engine.iactivity(\n "act.sun.discovers",\n [label2, this._host.renderAbsolute(amountCalculated)],\n "ks-faith"\n );\n }\n } else {\n this._host.engine.storeForSummary(label2, amountCalculated, "build");\n if (amountCalculated === 1) {\n this._host.engine.iactivity("act.build", [label2], "ks-build");\n } else {\n this._host.engine.iactivity(\n "act.builds",\n [label2, this._host.renderAbsolute(amountCalculated)],\n "ks-build"\n );\n }\n }\n }\n getBuildMetaData(builds) {\n const metaData = {};\n for (const build of Object.values(builds)) {\n const buildInfo = this.getBuild(build.building, build.variant);\n if (buildInfo === null) {\n continue;\n }\n metaData[build.building] = buildInfo;\n const buildMetaData = mustExist(metaData[build.building]);\n if (!this._getBuildButton(build.building, build.variant)) {\n buildMetaData.rHidden = true;\n } else {\n const model = mustExist(this._getBuildButton(build.building, build.variant)).model;\n const panel = build.variant === UnicornItemVariant.Cryptotheology ? this._host.game.science.get("cryptotheology").researched : true;\n buildMetaData.rHidden = !((model == null ? void 0 : model.visible) && model.enabled && panel);\n }\n }\n return metaData;\n }\n /**\n * Retrieve information about an upgrade.\n *\n * @param name The name of the upgrade.\n * @param variant The variant of the upgrade.\n * @returns The build information for the upgrade.\n */\n getBuild(name, variant) {\n switch (variant) {\n case UnicornItemVariant.Ziggurat:\n return this._host.game.religion.getZU(name) ?? null;\n case UnicornItemVariant.OrderOfTheSun:\n return this._host.game.religion.getRU(name) ?? null;\n case UnicornItemVariant.Cryptotheology:\n return this._host.game.religion.getTU(name) ?? null;\n }\n throw new Error(`Unknown build: ${name} (${variant})`);\n }\n /**\n * Find the button that allows purchasing a given upgrade.\n *\n * @param name The name of the upgrade.\n * @param variant The variant of the upgrade.\n * @returns The button to buy the upgrade, or `null`.\n */\n _getBuildButton(name, variant) {\n let buttons;\n switch (variant) {\n case UnicornItemVariant.Ziggurat:\n buttons = this.manager.tab.zgUpgradeButtons;\n break;\n case UnicornItemVariant.OrderOfTheSun:\n buttons = this.manager.tab.rUpgradeButtons;\n break;\n case UnicornItemVariant.Cryptotheology:\n buttons = this.manager.tab.children[0].children[0].children;\n break;\n default:\n throw new Error(`Invalid variant \'${variant}\'`);\n }\n if (buttons.length === 0) {\n return null;\n }\n const button2 = buttons.find((button22) => button22.id === name) ?? null;\n if (button2 === null) {\n console.debug(...cl(`Couldn\'t find button for ${name}! This will likely create problems.`));\n }\n return button2;\n }\n _transformBtnSacrificeHelper(available, total, controller, model) {\n const conversionPercentage = available / total;\n const percentageInverse = 1 / conversionPercentage;\n const customController = new classes.ui.religion.TransformBtnController(\n game,\n controller.controllerOpts\n );\n const link = customController._newLink(model, percentageInverse);\n return new Promise((resolve) => {\n link.handler(new Event("decoy"), resolve);\n });\n }\n async _autoSacrificeUnicorns() {\n const unicorns = this._workshopManager.getResource("unicorns");\n const available = this._workshopManager.getValueAvailable("unicorns");\n if (!isNil(this._host.game.religionTab.sacrificeBtn) && negativeOneToInfinity(this.settings.sacrificeUnicorns.trigger) <= available && negativeOneToInfinity(this.settings.sacrificeUnicorns.trigger) <= unicorns.value) {\n const controller = this._host.game.religionTab.sacrificeBtn.controller;\n const model = this._host.game.religionTab.sacrificeBtn.model;\n if (isNil(model)) {\n return;\n }\n await this._transformBtnSacrificeHelper(available, unicorns.value, controller, model);\n const availableNow = this._workshopManager.getValueAvailable("unicorns");\n const cost = available - availableNow;\n this._host.engine.iactivity(\n "act.sacrificeUnicorns",\n [this._host.game.getDisplayValueExt(cost)],\n "ks-faith"\n );\n this._host.engine.storeForSummary(\n this._host.engine.i18n("$resources.unicorns.title"),\n cost,\n "refine"\n );\n }\n }\n async _autoSacrificeAlicorns(context) {\n const alicorns = this._workshopManager.getResource("alicorn");\n const available = this._workshopManager.getValueAvailable("alicorn");\n if (!isNil(this._host.game.religionTab.sacrificeAlicornsBtn) && negativeOneToInfinity(this.settings.sacrificeAlicorns.trigger) <= available && negativeOneToInfinity(this.settings.sacrificeAlicorns.trigger) <= alicorns.value) {\n this._host.game.religionTab.sacrificeAlicornsBtn.render();\n const controller = this._host.game.religionTab.sacrificeAlicornsBtn.controller;\n const model = this._host.game.religionTab.sacrificeAlicornsBtn.model;\n if (isNil(model)) {\n context.requestGameUiRefresh = true;\n return;\n }\n await this._transformBtnSacrificeHelper(available, alicorns.value, controller, model);\n const availableNow = this._workshopManager.getValueAvailable("alicorn");\n const cost = available - availableNow;\n this._host.engine.iactivity(\n "act.sacrificeAlicorns",\n [this._host.game.getDisplayValueExt(cost)],\n "ks-faith"\n );\n this._host.engine.storeForSummary(\n this._host.engine.i18n("$resources.alicorn.title"),\n cost,\n "refine"\n );\n }\n }\n _autoTears(context) {\n const tears = this._workshopManager.getResource("tears");\n const available = this._workshopManager.getValueAvailable("tears");\n const sorrow = this._workshopManager.getResource("sorrow");\n if (!isNil(this._host.game.religionTab.refineBtn) && negativeOneToInfinity(this.settings.refineTears.trigger) <= available && negativeOneToInfinity(this.settings.refineTears.trigger) <= tears.value && sorrow.value < sorrow.maxValue) {\n const availableForConversion = available - this.settings.refineTears.trigger;\n if (availableForConversion < 1e4) {\n return;\n }\n const controller = this._host.game.religionTab.refineBtn.controller;\n const model = this._host.game.religionTab.refineBtn.model;\n if (isNil(model)) {\n context.requestGameUiRefresh = true;\n return;\n }\n controller.buyItem(model, new Event("decoy"), availableForConversion);\n const availableNow = this._workshopManager.getValueAvailable("tears");\n const cost = available - availableNow;\n this._host.engine.iactivity(\n "act.refineTears",\n [this._host.game.getDisplayValueExt(cost)],\n "ks-faith"\n );\n this._host.engine.storeForSummary(\n this._host.engine.i18n("$resources.tears.title"),\n cost,\n "refine"\n );\n }\n }\n async _autoTCs(context) {\n const timeCrystals = this._workshopManager.getResource("timeCrystal");\n const available = this._workshopManager.getValueAvailable("timeCrystal");\n if (!isNil(this._host.game.religionTab.refineTCBtn) && negativeOneToInfinity(this.settings.refineTimeCrystals.trigger) <= available && negativeOneToInfinity(this.settings.refineTimeCrystals.trigger) <= timeCrystals.value) {\n const controller = this._host.game.religionTab.refineTCBtn.controller;\n const model = this._host.game.religionTab.refineTCBtn.model;\n if (isNil(model)) {\n context.requestGameUiRefresh = true;\n return;\n }\n await this._transformBtnSacrificeHelper(available, timeCrystals.value, controller, model);\n const availableNow = this._workshopManager.getValueAvailable("timeCrystal");\n const cost = available - availableNow;\n this._host.engine.iactivity(\n "act.refineTCs",\n [this._host.game.getDisplayValueExt(cost)],\n "ks-faith"\n );\n this._host.engine.storeForSummary(\n this._host.engine.i18n("$resources.timeCrystal.title"),\n cost,\n "refine"\n );\n }\n }\n _autoTAP() {\n const faith = this._workshopManager.getResource("faith");\n const faithLevel = faith.value / faith.maxValue;\n if (this.settings.transcend.enabled && this.settings.autoPraise.trigger - 0.02 <= faithLevel) {\n this._autoTranscend();\n }\n if (this.settings.autoPraise.trigger <= faithLevel) {\n if (this.settings.adore.enabled && mustExist(this._host.game.religion.getRU("apocripha")).on) {\n this._autoAdore(this.settings.adore.trigger);\n }\n if (this.settings.autoPraise.enabled) {\n this._autoPraise();\n }\n }\n }\n _autoAdore(trigger) {\n const faith = this._workshopManager.getResource("faith");\n const worship = this._host.game.religion.faith;\n const epiphany = this._host.game.religion.faithRatio;\n const transcendenceReached = mustExist(this._host.game.religion.getRU("transcendence")).on;\n const transcendenceTierCurrent = transcendenceReached ? this._host.game.religion.transcendenceTier : 0;\n const maxSolarRevolution = 10 + this._host.game.getEffect("solarRevolutionLimit");\n const triggerSolarRevolution = maxSolarRevolution * trigger;\n const epiphanyIncrease = worship / 1e6 * transcendenceTierCurrent * transcendenceTierCurrent * 1.01;\n const epiphanyAfterAdore = epiphany + epiphanyIncrease;\n const worshipAfterAdore = 0.01 + faith.value * (1 + this._host.game.getUnlimitedDR(epiphanyAfterAdore, 0.1) * 0.1);\n const solarRevolutionAfterAdore = this._host.game.getLimitedDR(\n this._host.game.getUnlimitedDR(worshipAfterAdore, 1e3) / 100,\n maxSolarRevolution\n );\n if (triggerSolarRevolution <= solarRevolutionAfterAdore) {\n this._host.game.religion._resetFaithInternal(1.01);\n this._host.engine.iactivity(\n "act.adore",\n [\n this._host.game.getDisplayValueExt(worship),\n this._host.game.getDisplayValueExt(epiphanyIncrease)\n ],\n "ks-adore"\n );\n this._host.engine.storeForSummary("adore", epiphanyIncrease);\n }\n }\n _autoTranscend() {\n var _a, _b;\n let epiphany = this._host.game.religion.faithRatio;\n const transcendenceReached = mustExist(this._host.game.religion.getRU("transcendence")).on;\n let transcendenceTierCurrent = transcendenceReached ? this._host.game.religion.transcendenceTier : 0;\n if (transcendenceReached) {\n const adoreIncreaseRatio = ((transcendenceTierCurrent + 2) / (transcendenceTierCurrent + 1)) ** 2;\n const needNextLevel = this._host.game.religion._getTranscendTotalPrice(transcendenceTierCurrent + 1) - this._host.game.religion._getTranscendTotalPrice(transcendenceTierCurrent);\n const x = needNextLevel;\n const k = adoreIncreaseRatio;\n const epiphanyRecommend = (1 - k + Math.sqrt(80 * (k * k - 1) * x + (k - 1) * (k - 1))) * k / (40 * (k + 1) * (k + 1) * (k - 1)) + x + x / (k * k - 1);\n if (epiphanyRecommend <= epiphany) {\n this._host.game.religion.faithRatio -= needNextLevel;\n this._host.game.religion.tcratio += needNextLevel;\n this._host.game.religion.transcendenceTier += 1;\n const atheism = mustExist(this._host.game.challenges.getChallenge("atheism"));\n (_a = atheism.calculateEffects) == null ? void 0 : _a.call(atheism, atheism, this._host.game);\n const blackObelisk = mustExist(this._host.game.religion.getTU("blackObelisk"));\n (_b = blackObelisk.calculateEffects) == null ? void 0 : _b.call(blackObelisk, blackObelisk, this._host.game);\n this._host.game.msg(\n this._host.engine.i18n("$religion.transcend.msg.success", [\n this._host.game.religion.transcendenceTier\n ])\n );\n epiphany = this._host.game.religion.faithRatio;\n transcendenceTierCurrent = this._host.game.religion.transcendenceTier;\n this._host.engine.iactivity(\n "act.transcend",\n [this._host.game.getDisplayValueExt(needNextLevel), transcendenceTierCurrent],\n "ks-transcend"\n );\n this._host.engine.storeForSummary("transcend", 1);\n }\n }\n }\n _autoPraise() {\n const faith = this._workshopManager.getResource("faith");\n const apocryphaBonus = this._host.game.religion.getApocryphaBonus();\n const worshipIncrease = faith.value * (1 + apocryphaBonus);\n this._host.engine.storeForSummary("praise", worshipIncrease);\n this._host.engine.iactivity(\n "act.praise",\n [\n this._host.game.getDisplayValueExt(faith.value),\n this._host.game.getDisplayValueExt(worshipIncrease)\n ],\n "ks-praise"\n );\n this._host.game.religion.praise();\n }\n }\n class PolicySetting extends Setting {\n constructor(policy, enabled = false) {\n super(enabled);\n __privateAdd(this, _policy);\n __privateSet(this, _policy, policy);\n }\n get policy() {\n return __privateGet(this, _policy);\n }\n }\n _policy = new WeakMap();\n class PolicySettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "policies");\n this.policies = this.initPolicies();\n }\n initPolicies() {\n const items = {};\n for (const item of Policies) {\n items[item] = new PolicySetting(item);\n }\n return items;\n }\n static validateGame(game2, settings) {\n const inSettings = Object.keys(settings.policies);\n const inGame = game2.science.policies.map((policy) => policy.name);\n const missingInSettings = difference(inGame, inSettings);\n const redundantInSettings = difference(inSettings, inGame);\n for (const policy of missingInSettings) {\n console.warn(...cl(`The policy \'${policy}\' is not tracked in Kitten Scientists!`));\n }\n for (const policy of redundantInSettings) {\n console.warn(...cl(`The policy \'${policy}\' is not a policy in Kittens Game!`));\n }\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.policies, settings.policies, (policy, item) => {\n policy.enabled = (item == null ? void 0 : item.enabled) ?? policy.enabled;\n });\n }\n }\n class TechSetting extends SettingTrigger {\n constructor(tech, enabled = false) {\n super(enabled, -1);\n __privateAdd(this, _tech);\n __privateSet(this, _tech, tech);\n }\n get tech() {\n return __privateGet(this, _tech);\n }\n }\n _tech = new WeakMap();\n class TechSettings extends SettingTrigger {\n constructor(enabled = false) {\n super(enabled, -1);\n __publicField(this, "techs");\n this.techs = this.initTechs();\n }\n initTechs() {\n const items = {};\n for (const item of Technologies) {\n items[item] = new TechSetting(item);\n }\n return items;\n }\n static validateGame(game2, settings) {\n const inSettings = Object.keys(settings.techs);\n const inGame = game2.science.techs.map((tech) => tech.name);\n const missingInSettings = difference(inGame, inSettings);\n const redundantInSettings = difference(inSettings, inGame);\n for (const tech of missingInSettings) {\n if (TechnologiesIgnored.includes(tech)) {\n continue;\n }\n console.warn(...cl(`The technology \'${tech}\' is not tracked in Kitten Scientists!`));\n }\n for (const tech of redundantInSettings) {\n if (TechnologiesIgnored.includes(tech)) {\n console.info(\n ...cl(\n `The technology \'${tech}\' is a technology in Kittens Game, but it\'s no longer used.`\n )\n );\n continue;\n }\n console.warn(...cl(`The technology \'${tech}\' is not a technology in Kittens Game!`));\n }\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.techs, settings.techs, (tech, item) => {\n tech.enabled = (item == null ? void 0 : item.enabled) ?? tech.enabled;\n tech.trigger = (item == null ? void 0 : item.trigger) ?? tech.trigger;\n });\n }\n }\n class ScienceSettings extends Setting {\n constructor(enabled = false, policies = new PolicySettings(), techs = new TechSettings(), observe = new Setting()) {\n super(enabled);\n __publicField(this, "policies");\n __publicField(this, "techs");\n __publicField(this, "observe");\n this.policies = policies;\n this.techs = techs;\n this.observe = observe;\n }\n static validateGame(game2, settings) {\n PolicySettings.validateGame(game2, settings.policies);\n TechSettings.validateGame(game2, settings.techs);\n }\n load(settings) {\n var _a;\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n this.policies.load(settings.policies);\n this.techs.load(settings.techs);\n this.observe.enabled = ((_a = settings.observe) == null ? void 0 : _a.enabled) ?? this.observe.enabled;\n }\n }\n class UpgradeManager {\n constructor(host) {\n __publicField(this, "_host");\n this._host = host;\n }\n upgrade(upgrade, variant) {\n let success = false;\n if (variant === "policy") {\n const itemMetaRaw = game.getUnlockByName(upgrade.name, "policies");\n const controller = new classes.ui.PolicyBtnController(this._host.game);\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n success = UpgradeManager.skipConfirm(() => controller.buyItem(model)).itemBought;\n } else if (variant === "science") {\n const itemMetaRaw = game.getUnlockByName(upgrade.name, "tech");\n const controller = new com.nuclearunicorn.game.ui.TechButtonController(\n this._host.game\n );\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n success = UpgradeManager.skipConfirm(() => controller.buyItem(model)).itemBought;\n } else {\n const itemMetaRaw = game.getUnlockByName(upgrade.name, "upgrades");\n const controller = new com.nuclearunicorn.game.ui.UpgradeButtonController(\n this._host.game\n );\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n success = UpgradeManager.skipConfirm(() => controller.buyItem(model)).itemBought;\n }\n if (!success) {\n return false;\n }\n const label2 = upgrade.label;\n if (variant === "workshop") {\n this._host.engine.storeForSummary(label2, 1, "upgrade");\n this._host.engine.iactivity("upgrade.upgrade", [label2], "ks-upgrade");\n } else if (variant === "policy") {\n this._host.engine.iactivity("upgrade.policy", [label2]);\n } else if (variant === "science") {\n this._host.engine.storeForSummary(label2, 1, "research");\n this._host.engine.iactivity("upgrade.tech", [label2], "ks-research");\n }\n return true;\n }\n /**\n * Run a piece of code that might invoke UI confirmation and\n * skip that UI confirmation.\n *\n * @param action The function to run without UI confirmation.\n * @returns Whatever `action` returns.\n */\n static async skipConfirmAsync(action) {\n const originalConfirm = game.ui.confirm;\n try {\n game.ui.confirm = () => true;\n return await action();\n } finally {\n game.ui.confirm = originalConfirm;\n }\n }\n static skipConfirm(action) {\n const originalConfirm = game.ui.confirm;\n try {\n game.ui.confirm = () => true;\n return action();\n } finally {\n game.ui.confirm = originalConfirm;\n }\n }\n }\n const sleep = (duration) => {\n return new Promise((resolve) => setTimeout(resolve, duration));\n };\n const FallbackLocale = "en-US";\n const TIMEOUT_DEFAULT = 2 * 60 * 1e3;\n const TIMEOUT_OVERRIDE = "localStorage" in globalThis && !isNil(localStorage["ks.timeout"]) ? Number(localStorage["ks.timeout"]) : void 0;\n class UserScriptLoader {\n constructor() {\n /**\n * Stores if we caught the `game/start` signal from the game.\n */\n __publicField(this, "_gameStartSignal");\n __publicField(this, "_gameStartSignalResolver");\n __publicField(this, "_possibleEngineState");\n }\n static tryEngineStateFromSaveData(saveDataKey, saveData) {\n const saveDataProxy = saveData;\n if (!(saveDataKey in saveDataProxy)) {\n console.debug(...cl(`Failed: \\`${saveDataKey}\\` not found in save data.`));\n return void 0;\n }\n const ksData = saveDataProxy.ks;\n if (!("state" in ksData)) {\n console.debug(...cl(`Failed: \\`${saveDataKey}.state\\` not found in save data.`));\n return void 0;\n }\n const state = ksData.state;\n if (!Array.isArray(state)) {\n console.debug(...cl(`Failed: \\`${saveDataKey}.state\\` not \\`Array\\`.`));\n return void 0;\n }\n return state[0];\n }\n async waitForGame(UserScript, saveDataKey, timeout = TIMEOUT_OVERRIDE ?? TIMEOUT_DEFAULT) {\n if (UserScriptLoader._isGameLoaded()) {\n const game2 = mustExist(UserScriptLoader.window.game);\n const i18nEngine = mustExist(UserScriptLoader.window.$I);\n const gameLanguage = localStorage["com.nuclearunicorn.kittengame.language"];\n return new UserScript(game2, i18nEngine, gameLanguage, this._possibleEngineState);\n }\n const signals = [sleep(2e3)];\n if (isNil(this._gameStartSignal) && typeof UserScriptLoader.window.dojo !== "undefined") {\n this._gameStartSignal = new Promise((resolve) => {\n this._gameStartSignalResolver = resolve;\n });\n const subGameStart = UserScriptLoader.window.dojo.subscribe("game/start", () => {\n console.debug(\n ...cl(`\'game/start\' signal caught. Fast-tracking script load for \'${saveDataKey}\'...`)\n );\n mustExist(this._gameStartSignalResolver)(true);\n UserScriptLoader.window.dojo.unsubscribe(subGameStart);\n });\n if (saveDataKey !== void 0) {\n const subServerLoad = UserScriptLoader.window.dojo.subscribe(\n "server/load",\n (saveData) => {\n console.info(\n ...cl(\n `\'server/load\' signal caught. Looking for script state with key \'${saveDataKey}\' in save data...`\n )\n );\n const state = UserScriptLoader.tryEngineStateFromSaveData(saveDataKey, saveData);\n if (!state) {\n console.info(\n ...cl(\n `The Kittens Game save data did not contain a script state for \'${saveDataKey}\'.`\n )\n );\n return;\n }\n console.info(\n ...cl(\n `Found key \'${saveDataKey}\'! Provided save data will be used as seed for next script instance.`\n )\n );\n this._possibleEngineState = state;\n UserScriptLoader.window.dojo.unsubscribe(subServerLoad);\n }\n );\n }\n }\n if (!isNil(this._gameStartSignal)) {\n signals.push(this._gameStartSignal);\n }\n if (timeout < 0) {\n throw new Error(\n "Unable to find game. Giving up. Maybe the game is not exported at `window.game`?"\n );\n }\n console.debug(...cl(`Waiting for game... (timeout: ${Math.round(timeout / 1e3)}s)`));\n await Promise.race(signals);\n return this.waitForGame(UserScript, saveDataKey, timeout - 2e3);\n }\n static _isGameLoaded() {\n var _a;\n return !isNil(UserScriptLoader.window.game) && (((_a = UserScriptLoader.window.document.getElementById("game")) == null ? void 0 : _a.checkVisibility()) ?? false) && !isNil(UserScriptLoader.window.$I);\n }\n static get window() {\n try {\n return mustExist(unsafeWindow);\n } catch (_error) {\n return window;\n }\n }\n }\n class ScienceManager extends UpgradeManager {\n constructor(host, workshopManager, settings = new ScienceSettings()) {\n super(host);\n __publicField(this, "manager");\n __publicField(this, "settings");\n __publicField(this, "_workshopManager");\n this.settings = settings;\n this.manager = new TabManager(this._host, "Science");\n this._workshopManager = workshopManager;\n }\n async tick(_context) {\n if (!this.settings.enabled) {\n return;\n }\n this.manager.render();\n if (this.settings.techs.enabled && this._host.game.tabs[2].visible) {\n await this.autoUnlock();\n }\n if (this.settings.policies.enabled && this._host.game.tabs[2].visible) {\n await this.autoPolicy();\n }\n if (this.settings.observe.enabled) {\n this.observeStars();\n }\n }\n async autoUnlock() {\n const techs = this._host.game.science.techs;\n const toUnlock = new Array();\n workLoop: for (const setting2 of Object.values(this.settings.techs.techs)) {\n if (!setting2.enabled) {\n continue;\n }\n const tech = techs.find((subject) => subject.name === setting2.tech);\n if (isNil(tech)) {\n console.error(...cl(`Tech \'${setting2.tech}\' not found in game!`));\n continue;\n }\n if (tech.researched || !tech.unlocked) {\n continue;\n }\n let prices = UserScriptLoader.window.dojo.clone(tech.prices);\n prices = this._host.game.village.getEffectLeader("scientist", prices);\n for (const price of prices) {\n const available = this._workshopManager.getValueAvailable(price.name);\n const resource = this._workshopManager.getResource(price.name);\n const trigger = Engine.evaluateSubSectionTrigger(\n this.settings.techs.trigger,\n setting2.trigger\n );\n if (trigger < 0 || available < resource.maxValue * trigger || available < price.val) {\n continue workLoop;\n }\n }\n toUnlock.push(tech);\n }\n for (const item of toUnlock) {\n await this.upgrade(item, "science");\n }\n }\n async autoPolicy() {\n const policies = this._host.game.science.policies;\n const toUnlock = new Array();\n for (const setting2 of Object.values(this.settings.policies.policies)) {\n if (!setting2.enabled) {\n continue;\n }\n const targetPolicy = policies.find((subject) => subject.name === setting2.policy);\n if (isNil(targetPolicy)) {\n console.error(...cl(`Policy \'${setting2.policy}\' not found in game!`));\n continue;\n }\n if (!targetPolicy.researched && !targetPolicy.blocked && targetPolicy.unlocked) {\n if (targetPolicy.requiredLeaderJob === void 0 || this._host.game.village.leader !== null && this._host.game.village.leader.job === targetPolicy.requiredLeaderJob) {\n toUnlock.push(targetPolicy);\n }\n }\n }\n for (const item of toUnlock) {\n await this.upgrade(item, "policy");\n }\n }\n /**\n * If there is currently an astronomical event, observe it.\n */\n observeStars() {\n if (this._host.game.calendar.observeBtn !== null) {\n this._host.game.calendar.observeHandler();\n this._host.engine.iactivity("act.observe", [], "ks-star");\n this._host.engine.storeForSummary("stars", 1);\n }\n }\n }\n class MissionSetting extends Setting {\n constructor(mission, enabled = false) {\n super(enabled);\n __privateAdd(this, _mission);\n __privateSet(this, _mission, mission);\n }\n get mission() {\n return __privateGet(this, _mission);\n }\n }\n _mission = new WeakMap();\n class MissionSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "missions");\n this.missions = this.initMissions();\n }\n initMissions() {\n const items = {};\n for (const item of Missions) {\n items[item] = new MissionSetting(item);\n }\n return items;\n }\n static validateGame(game2, settings) {\n const inSettings = Object.keys(settings.missions);\n const inGame = game2.space.programs.map((program) => program.name);\n const missingInSettings = difference(inGame, inSettings);\n const redundantInSettings = difference(inSettings, inGame);\n for (const mission of missingInSettings) {\n console.warn(...cl(`The space mission \'${mission}\' is not tracked in Kitten Scientists!`));\n }\n for (const mission of redundantInSettings) {\n console.warn(...cl(`The space mission \'${mission}\' is not a space mission in Kittens Game!`));\n }\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.missions, settings.missions, (mission, item) => {\n mission.enabled = (item == null ? void 0 : item.enabled) ?? mission.enabled;\n });\n }\n }\n class SpaceBuildingSetting extends SettingTriggerMax {\n constructor(building) {\n super(false, -1, 0);\n __privateAdd(this, _building3);\n __privateSet(this, _building3, building);\n }\n get building() {\n return __privateGet(this, _building3);\n }\n }\n _building3 = new WeakMap();\n class SpaceSettings extends SettingTrigger {\n constructor(enabled = false, trigger = -1, unlockMissions = new MissionSettings()) {\n super(enabled, trigger);\n __publicField(this, "buildings");\n __publicField(this, "unlockMissions");\n this.buildings = this.initBuildings();\n this.unlockMissions = unlockMissions;\n }\n initBuildings() {\n const items = {};\n for (const item of SpaceBuildings) {\n items[item] = new SpaceBuildingSetting(item);\n }\n return items;\n }\n static validateGame(game2, settings) {\n MissionSettings.validateGame(game2, settings.unlockMissions);\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n building.max = (item == null ? void 0 : item.max) ?? building.max;\n building.trigger = (item == null ? void 0 : item.trigger) ?? building.trigger;\n });\n this.unlockMissions.load(settings.unlockMissions);\n }\n }\n class SpaceManager {\n constructor(host, workshopManager, settings = new SpaceSettings()) {\n __publicField(this, "_host");\n __publicField(this, "settings");\n __publicField(this, "manager");\n __publicField(this, "_bulkManager");\n __publicField(this, "_workshopManager");\n this._host = host;\n this.settings = settings;\n this.manager = new TabManager(this._host, "Space");\n this._workshopManager = workshopManager;\n this._bulkManager = new BulkPurchaseHelper(this._host, this._workshopManager);\n }\n tick(context) {\n if (!this.settings.enabled) {\n return;\n }\n this.manager.render();\n this.autoBuild(context);\n if (this.settings.unlockMissions.enabled) {\n this.autoUnlock(context);\n }\n }\n /**\n * Try to build as many of the passed buildings as possible.\n * Usually, this is called at each iteration of the automation engine to\n * handle the building of items on the Space tab.\n *\n * @param builds The buildings to build.\n */\n autoBuild(context, builds = this.settings.buildings) {\n const bulkManager = this._bulkManager;\n const sectionTrigger = this.settings.trigger;\n const metaData = {};\n for (const build of Object.values(builds)) {\n metaData[build.building] = this.getBuild(build.building);\n }\n const buildList = bulkManager.bulk(builds, metaData, sectionTrigger, "Space");\n for (const build of buildList) {\n if (build.count <= 0) {\n continue;\n }\n if (0 === this.build(build.id, build.count)) {\n continue;\n }\n context.requestGameUiRefresh = true;\n }\n }\n autoUnlock(context) {\n var _a, _b;\n if (!this._host.game.tabs[6].visible) {\n return;\n }\n const missions = this._host.game.space.meta[0].meta;\n missionLoop: for (let i = 0; i < missions.length; i++) {\n if (0 < missions[i].val || !missions[i].unlocked || !this.settings.unlockMissions.missions[missions[i].name].enabled) {\n continue;\n }\n const model = (_a = this.manager.tab.GCPanel) == null ? void 0 : _a.children[i];\n if (isNil(model)) {\n return;\n }\n const prices = mustExist((_b = model.model) == null ? void 0 : _b.prices);\n for (const resource of prices) {\n if (this._workshopManager.getValueAvailable(resource.name) < resource.val) {\n continue missionLoop;\n }\n }\n model.domNode.click();\n context.requestGameUiRefresh = true;\n if (i === 7 || i === 12) {\n this._host.engine.iactivity("upgrade.space.mission", [missions[i].label], "ks-upgrade");\n } else {\n this._host.engine.iactivity("upgrade.space", [missions[i].label], "ks-upgrade");\n }\n }\n }\n build(name, amount) {\n let amountCalculated = amount;\n const amountTemp = amountCalculated;\n let label2;\n const itemMetaRaw = game.getUnlockByName(name, "spaceBuilding");\n const controller = new classes.ui.space.PlanetBuildingBtnController(\n this._host.game\n );\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);\n label2 = itemMetaRaw.label;\n if (amountCalculated !== amountTemp) {\n console.warn(\n ...cl(`${label2} Amount ordered: ${amountTemp} Amount Constructed: ${amountCalculated}`)\n );\n if (amountCalculated === 0) {\n return 0;\n }\n }\n this._host.engine.storeForSummary(label2, amountCalculated, "build");\n if (amountCalculated === 1) {\n this._host.engine.iactivity("act.build", [label2], "ks-build");\n } else {\n this._host.engine.iactivity(\n "act.builds",\n [label2, this._host.renderAbsolute(amountCalculated)],\n "ks-build"\n );\n }\n return amountCalculated;\n }\n getBuild(name) {\n return this._host.game.space.getBuilding(name);\n }\n _getBuildButton(id) {\n const panels = this.manager.tab.planetPanels;\n if (isNil(panels)) {\n return null;\n }\n let button2 = null;\n for (const panel of panels) {\n button2 = panel.children.find((child) => child.id === id) ?? null;\n if (!isNil(button2)) {\n return button2;\n }\n }\n if (button2 === null) {\n throw new Error(`Couldn\'t find button for ${id}!`);\n }\n }\n }\n var LogFilterItemVariant = /* @__PURE__ */ ((LogFilterItemVariant2) => {\n LogFilterItemVariant2["build"] = "ks-activity type_ks-build";\n LogFilterItemVariant2["craft"] = "ks-activity type_ks-craft";\n LogFilterItemVariant2["upgrade"] = "ks-activity type_ks-upgrade";\n LogFilterItemVariant2["research"] = "ks-activity type_ks-research";\n LogFilterItemVariant2["trade"] = "ks-activity type_ks-trade";\n LogFilterItemVariant2["hunt"] = "ks-activity type_ks-hunt";\n LogFilterItemVariant2["praise"] = "ks-activity type_ks-praise";\n LogFilterItemVariant2["adore"] = "ks-activity type_ks-adore";\n LogFilterItemVariant2["transcend"] = "ks-activity type_ks-transcend";\n LogFilterItemVariant2["faith"] = "ks-activity type_ks-faith";\n LogFilterItemVariant2["accelerate"] = "ks-activity type_ks-accelerate";\n LogFilterItemVariant2["timeSkip"] = "ks-activity type_ks-timeSkip";\n LogFilterItemVariant2["festival"] = "ks-activity type_ks-festival";\n LogFilterItemVariant2["star"] = "ks-activity type_ks-star";\n LogFilterItemVariant2["distribute"] = "ks-activity type_ks-distribute";\n LogFilterItemVariant2["promote"] = "ks-activity type_ks-promote";\n LogFilterItemVariant2["misc"] = "ks-activity";\n return LogFilterItemVariant2;\n })(LogFilterItemVariant || {});\n const FilterItems = [\n "accelerate",\n "adore",\n "build",\n "craft",\n "distribute",\n "faith",\n "festival",\n "hunt",\n "misc",\n "praise",\n "promote",\n "research",\n "star",\n "timeSkip",\n "trade",\n "transcend",\n "upgrade"\n ];\n class LogFilterSettingsItem extends Setting {\n constructor(variant) {\n super(true);\n __privateAdd(this, _variant2);\n __privateSet(this, _variant2, variant);\n }\n get variant() {\n return __privateGet(this, _variant2);\n }\n }\n _variant2 = new WeakMap();\n class LogFilterSettings extends Setting {\n constructor(enabled = false, disableKGLog = new Setting(true)) {\n super(enabled);\n __publicField(this, "filters");\n __publicField(this, "disableKGLog");\n this.filters = this.initFilters();\n this.disableKGLog = disableKGLog;\n }\n initFilters() {\n const items = {};\n for (const item of FilterItems) {\n items[item] = new LogFilterSettingsItem(LogFilterItemVariant[item]);\n }\n return items;\n }\n load(settings) {\n var _a;\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.filters, settings.filters, (filter, item) => {\n filter.enabled = (item == null ? void 0 : item.enabled) ?? filter.enabled;\n });\n this.disableKGLog.enabled = ((_a = settings.disableKGLog) == null ? void 0 : _a.enabled) ?? this.disableKGLog.enabled;\n }\n }\n class UpgradeSettingsItem extends SettingTrigger {\n constructor(upgrade, enabled = false) {\n super(enabled, -1);\n __privateAdd(this, _upgrade2);\n __privateSet(this, _upgrade2, upgrade);\n }\n get upgrade() {\n return __privateGet(this, _upgrade2);\n }\n }\n _upgrade2 = new WeakMap();\n class UpgradeSettings extends SettingTrigger {\n constructor(enabled = false) {\n super(enabled, -1);\n __publicField(this, "upgrades");\n this.upgrades = this.initUpgrades();\n }\n initUpgrades() {\n const items = {};\n for (const item of Upgrades) {\n items[item] = new UpgradeSettingsItem(item);\n }\n return items;\n }\n static validateGame(game2, settings) {\n const inSettings = Object.keys(settings.upgrades);\n const inGame = game2.workshop.upgrades.map((upgrade) => upgrade.name);\n const missingInSettings = difference(inGame, inSettings);\n const redundantInSettings = difference(inSettings, inGame);\n for (const upgrade of missingInSettings) {\n console.warn(...cl(`The workshop upgrade \'${upgrade}\' is not tracked in Kitten Scientists!`));\n }\n for (const upgrade of redundantInSettings) {\n console.warn(...cl(`The workshop upgrade \'${upgrade}\' is not an upgrade in Kittens Game!`));\n }\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.upgrades, settings.upgrades, (upgrade, item) => {\n upgrade.enabled = (item == null ? void 0 : item.enabled) ?? upgrade.enabled;\n upgrade.trigger = (item == null ? void 0 : item.trigger) ?? upgrade.trigger;\n });\n }\n }\n class CraftSettingsItem extends SettingLimitedMaxTrigger {\n constructor(resource, enabled = false, limited = true) {\n super(enabled, limited);\n __privateAdd(this, _resource);\n __privateSet(this, _resource, resource);\n }\n get resource() {\n return __privateGet(this, _resource);\n }\n }\n _resource = new WeakMap();\n class WorkshopSettings extends SettingTrigger {\n constructor(enabled = false, trigger = -1, unlockUpgrades = new UpgradeSettings(), shipOverride = new Setting()) {\n super(enabled, trigger);\n __publicField(this, "resources");\n __publicField(this, "shipOverride");\n __publicField(this, "unlockUpgrades");\n this.resources = this.initResources();\n this.shipOverride = shipOverride;\n this.unlockUpgrades = unlockUpgrades;\n }\n initResources() {\n const items = {};\n for (const item of ResourcesCraftable) {\n items[item] = new CraftSettingsItem(item);\n }\n return items;\n }\n static validateGame(game2, settings) {\n const inSettings = Object.keys(settings.resources);\n const inGame = game2.workshop.crafts.map((craft) => craft.name);\n const missingInSettings = difference(inGame, inSettings);\n const redundantInSettings = difference(inSettings, inGame);\n for (const craft of missingInSettings) {\n console.warn(...cl(`The workshop craft \'${craft}\' is not tracked in Kitten Scientists!`));\n }\n for (const craft of redundantInSettings) {\n console.warn(...cl(`The workshop craft \'${craft}\' is not an upgrade in Kittens Game!`));\n }\n UpgradeSettings.validateGame(game2, settings.unlockUpgrades);\n }\n load(settings) {\n var _a;\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.resources, settings.resources, (resource, item) => {\n resource.enabled = (item == null ? void 0 : item.enabled) ?? resource.enabled;\n resource.limited = (item == null ? void 0 : item.limited) ?? resource.limited;\n resource.max = (item == null ? void 0 : item.max) ?? resource.max;\n resource.trigger = (item == null ? void 0 : item.trigger) ?? resource.trigger;\n });\n this.unlockUpgrades.load(settings.unlockUpgrades);\n this.shipOverride.enabled = ((_a = settings.shipOverride) == null ? void 0 : _a.enabled) ?? this.shipOverride.enabled;\n }\n }\n class WorkshopManager extends UpgradeManager {\n constructor(host, settings = new WorkshopSettings()) {\n super(host);\n __publicField(this, "settings");\n __publicField(this, "manager");\n this.settings = settings;\n this.manager = new TabManager(this._host, "Workshop");\n }\n tick(_context) {\n if (!this.settings.enabled) {\n return Promise.resolve();\n }\n this.autoCraft();\n this.refreshStock();\n if (this.settings.unlockUpgrades.enabled) {\n this.manager.render();\n return this.autoUnlock();\n }\n return Promise.resolve();\n }\n async autoUnlock() {\n if (!this._host.game.workshopTab.visible) {\n return;\n }\n const upgrades = this._host.game.workshop.upgrades;\n const toUnlock = new Array();\n workLoop: for (const setting2 of Object.values(this.settings.unlockUpgrades.upgrades)) {\n if (!setting2.enabled) {\n continue;\n }\n const upgrade = upgrades.find((subject) => subject.name === setting2.upgrade);\n if (isNil(upgrade)) {\n console.error(...cl(`Upgrade \'${setting2.upgrade}\' not found in game!`));\n continue;\n }\n if (upgrade.researched || !upgrade.unlocked) {\n continue;\n }\n let prices = UserScriptLoader.window.dojo.clone(upgrade.prices);\n prices = this._host.game.village.getEffectLeader("scientist", prices);\n for (const price of prices) {\n const available = this.getValueAvailable(price.name);\n const resource = this.getResource(price.name);\n const trigger = Engine.evaluateSubSectionTrigger(\n this.settings.unlockUpgrades.trigger,\n setting2.trigger\n );\n if (trigger < 0 || 0 < trigger && available < resource.maxValue * trigger || available < price.val) {\n continue workLoop;\n }\n }\n toUnlock.push(upgrade);\n }\n for (const item of toUnlock) {\n await this.upgrade(item, "workshop");\n }\n }\n /**\n * Try to craft as many of the passed resources as possible.\n * Usually, this is called at each iteration of the automation engine to\n * handle the crafting of items on the Workshop tab.\n *\n * @param crafts The resources to build.\n */\n autoCraft(crafts = this.settings.resources) {\n const craftRequests = /* @__PURE__ */ new Map();\n const sectionTrigger = this.settings.trigger;\n for (const craft of Object.values(crafts)) {\n const trigger = Engine.evaluateSubSectionTrigger(sectionTrigger, craft.trigger);\n if (trigger < 0 || !craft.enabled) {\n continue;\n }\n const current = !craft.max ? false : this.getResource(craft.resource);\n const max = negativeOneToInfinity(craft.max);\n if (current && max < current.value) {\n continue;\n }\n if (!this.singleCraftPossible(craft.resource)) {\n continue;\n }\n const materials = Object.keys(this.getMaterials(craft.resource));\n const requiredMaterials = materials.map((material) => this.getResource(material)).filter((material) => 0 < material.maxValue);\n const allMaterialsAboveTrigger = requiredMaterials.filter((material) => material.value / material.maxValue < trigger).length === 0;\n if (!allMaterialsAboveTrigger) {\n continue;\n }\n craftRequests.set(craft, {\n countRequested: 1,\n materials: materials.map((material) => ({\n consume: 0,\n resource: material\n }))\n });\n }\n if (craftRequests.size < 1) {\n return;\n }\n const billOfMaterials = /* @__PURE__ */ new Map();\n for (const [craft, request] of craftRequests) {\n for (const material of request.materials) {\n if (!billOfMaterials.has(material.resource)) {\n billOfMaterials.set(material.resource, new Array());\n }\n const consumers = mustExist(billOfMaterials.get(material.resource));\n consumers.push(craft.resource);\n }\n }\n for (const [, request] of craftRequests) {\n for (const material of request.materials) {\n const available = this.getValueAvailable(material.resource);\n material.consume = available / mustExist(billOfMaterials.get(material.resource)).length;\n }\n }\n for (const [craft, request] of craftRequests) {\n const materials = this.getMaterials(craft.resource);\n let amount = Number.MAX_VALUE;\n for (const material of request.materials) {\n const materialAmount = mustExist(materials[material.resource]);\n const materialResource = this.getResource(material.resource);\n if (\n // For unlimited crafts, assign all resources.\n !craft.limited || // Handle the ship override.\n craft.resource === "ship" && this.settings.shipOverride.enabled && this.getResource("ship").value < 243\n ) {\n amount = Math.min(amount, material.consume / materialAmount);\n continue;\n }\n const ratio = this._host.game.getResCraftRatio(craft.resource);\n const availableSource = this.getValueAvailable(material.resource) / mustExist(billOfMaterials.get(material.resource)).length;\n const availableTarget2 = this.getValueAvailable(craft.resource);\n const recipeRequires = materialAmount;\n const recipeProduces2 = 1 + ratio;\n const craftsPossible = availableSource / recipeRequires;\n const craftsDone = availableTarget2 / recipeProduces2;\n const orderDone = Math.max(0, Math.floor(Math.log(craftsDone) / Math.LN10 + 1e-9));\n amount = Math.min(\n // Whatever was previously assumed as the best amount.\n amount,\n // We want to craft the lowest amount of these values, as we\'re in the "limited" mode.\n Math.min(\n // We take the possible crafts as the baseline\n craftsPossible - // If the source material is one that has a storage capacity, and the storage is full,\n // then we want to allow all possible crafts to be crafted. So we subtract 0.\n (0 < materialResource.maxValue && materialResource.maxValue <= materialResource.value ? 0 : (\n // If the resource is not capped, we subtract the crafts we have already done.\n craftsDone\n )),\n // The safe limit is to buy the next higher order of magnitude of items, to not\n // waste all resources if the target resource is very low, like after a reset with chronospheres.\n 10 ** (orderDone + 1)\n ),\n // The amount of resources we could craft, based on our consume rate.\n material.consume / materialAmount\n );\n }\n const availableTarget = this.getValueAvailable(craft.resource);\n const recipeProduces = 1 + this._host.game.getResCraftRatio(craft.resource);\n const craftsMaxLimit = Number.MAX_VALUE / recipeProduces - availableTarget / recipeProduces;\n amount = Math.min(amount, craftsMaxLimit);\n request.countRequested = Math.max(\n 0,\n craft.max === -1 ? amount : Math.min(amount, (craft.max - availableTarget) / recipeProduces)\n );\n }\n for (const [craft, request] of craftRequests) {\n if (request.countRequested < 1) {\n continue;\n }\n this.craft(craft.resource, request.countRequested);\n }\n }\n /**\n * Craft a certain amount of items.\n *\n * @param name The resource to craft.\n * @param amount How many items of the resource to craft.\n */\n craft(name, amount) {\n let amountCalculated = Math.floor(amount);\n if (amountCalculated < 1) {\n return;\n }\n if (!this._canCraft(name, amountCalculated)) {\n return;\n }\n const craft = this.getCraft(name);\n const ratio = this._host.game.getResCraftRatio(craft.name);\n this._host.game.craft(craft.name, amountCalculated);\n const resourceName = mustExist(this._host.game.resPool.get(name)).title;\n amountCalculated = Number.parseFloat((amountCalculated * (1 + ratio)).toFixed(2));\n this._host.engine.storeForSummary(resourceName, amountCalculated, "craft");\n this._host.engine.iactivity(\n "act.craft",\n [this._host.game.getDisplayValueExt(amountCalculated), resourceName],\n "ks-craft"\n );\n }\n _canCraft(name, amount) {\n if (!this._host.game.workshopTab.visible && name !== "wood") {\n return false;\n }\n const craft = this.getCraft(name);\n const enabled = mustExist(this.settings.resources[name]).enabled;\n let result = false;\n if (craft.unlocked && enabled) {\n result = true;\n const prices = this._host.game.workshop.getCraftPrice(craft);\n for (const price of prices) {\n const value = this.getValueAvailable(price.name);\n if (value < price.val * amount) {\n result = false;\n }\n }\n }\n return result;\n }\n /**\n * Retrieve the resource information object from the game.\n *\n * @param name The name of the craftable resource.\n * @returns The information object for the resource.\n */\n getCraft(name) {\n const craft = this._host.game.workshop.getCraft(name);\n if (!craft) {\n throw new Error(`Unable to find craft \'${name}\'`);\n }\n return craft;\n }\n /**\n * Check if we have enough resources to craft a single craftable resource.\n *\n * @param name The name of the resource.\n * @returns `true` if the build is possible; `false` otherwise.\n */\n singleCraftPossible(name) {\n if (!this._host.game.workshopTab.visible && name !== "wood") {\n return false;\n }\n const materials = this.getMaterials(name);\n for (const [material, amount] of objectEntries(materials)) {\n if (this.getValueAvailable(material) < amount) {\n return false;\n }\n }\n return true;\n }\n /**\n * Returns a hash of the required source resources and their\n * amount to craft the given resource.\n *\n * @param name The resource to craft.\n * @returns The source resources you need and how many.\n */\n getMaterials(name) {\n const materials = {};\n const craft = this.getCraft(name);\n const prices = this._host.game.workshop.getCraftPrice(craft);\n for (const price of prices) {\n materials[price.name] = price.val;\n }\n return materials;\n }\n /**\n * Determine how much of a resource is produced per tick. For craftable resources,\n * this also includes how many of them we *could* craft this tick.\n *\n * @param resource The resource to retrieve the production for.\n * @param cacheManager A `CacheManager` to use in the process.\n * @param preTrade ?\n * @returns The amount of resources produced per tick, adjusted arbitrarily.\n */\n getTickVal(resource, cacheManager, preTrade = void 0) {\n let production = this._host.game.getResourcePerTick(resource.name, true);\n if (resource.craftable) {\n let minProd = Number.MAX_VALUE;\n const materials = this.getMaterials(resource.name);\n for (const [mat, amount] of objectEntries(materials)) {\n const rat = (1 + this._host.game.getResCraftRatio(resource.name)) / amount;\n const addProd = this.getTickVal(this.getResource(mat));\n if (addProd === "ignore") {\n continue;\n }\n minProd = Math.min(addProd * rat, minProd);\n }\n production += minProd !== Number.MAX_VALUE ? minProd : 0;\n }\n if (production <= 0 && (resource.name === "spice" || resource.name === "blueprint")) {\n return "ignore";\n }\n if (!preTrade && !isNil(cacheManager)) {\n production += cacheManager.getResValue(resource.name);\n }\n return production;\n }\n /**\n * Determine the resources and their amount that would usually result from a hunt.\n *\n * @returns The amounts of resources usually gained from hunting.\n */\n getAverageHunt() {\n const output = {};\n const hunterRatio = this._host.game.getEffect("hunterRatio") + this._host.game.village.getEffectLeader("manager", 0);\n output.furs = 40 + 32.5 * hunterRatio;\n output.ivory = 50 * Math.min(0.225 + 0.01 * hunterRatio, 0.5) + 40 * hunterRatio * Math.min(0.225 + 0.01 * hunterRatio, 0.5);\n output.unicorns = 0.05;\n if (this.getValue("zebras") >= 10) {\n output.bloodstone = this.getValue("bloodstone") === 0 ? 0.05 : 5e-4;\n }\n if (this._host.game.ironWill && this._host.game.workshop.get("goldOre").researched) {\n output.gold = 0.625 + 0.625 * hunterRatio;\n }\n return output;\n }\n /**\n * Retrieve the information object for a resource.\n *\n * @param name The resource to retrieve info for.\n * @returns The information object for the resource.\n */\n getResource(name) {\n const res = this._host.game.resPool.get(name);\n if (isNil(res)) {\n throw new Error(`Unable to find resource ${name}`);\n }\n return res;\n }\n /**\n * Determine how many items of a resource are currently available.\n *\n * @param name The resource.\n * @returns How many items are currently available.\n */\n getValue(name) {\n return this.getResource(name).value ?? 0;\n }\n /**\n * Determine how many items of the resource to always keep in stock.\n *\n * @param name The resource.\n * @returns How many items of the resource to always keep in stock.\n */\n getStock(name) {\n const resource = this._host.engine.settings.resources.resources[name];\n const stock = resource.enabled ? resource.stock : 0;\n return stock;\n }\n /**\n * Retrieve the consume rate for a resource.\n *\n * @param name - The resource.\n * @returns The consume rate for the resource.\n */\n getConsume(name) {\n const resource = this._host.engine.settings.resources.resources[name];\n const consume = resource.enabled ? resource.consume : 1;\n return consume;\n }\n /**\n * Determine how much of a resource is available for a certain operation\n * to use.\n *\n * @param name The resource to check.\n * @returns The available amount of the resource.\n */\n getValueAvailable(name) {\n let stock = this.getStock(name);\n if ("catnip" === name) {\n const pastureMeta = this._host.game.bld.getBuildingExt("pasture").meta;\n const aqueductMeta = this._host.game.bld.getBuildingExt("aqueduct").meta;\n const pastures = pastureMeta.stage === 0 ? pastureMeta.val : 0;\n const aqueducts = aqueductMeta.stage === 0 ? aqueductMeta.val : 0;\n const resPerTick = this.getPotentialCatnip(true, pastures, aqueducts);\n if (resPerTick < 0) {\n stock -= resPerTick * 202 * 5;\n }\n }\n let value = this.getValue(name);\n value = Math.max(value - stock, 0);\n const consume = this.getConsume(name);\n return value * consume;\n }\n /**\n * Determine how much catnip we have available to "work with" per tick.\n *\n * @param worstWeather Should the worst weather be assumed for this calculation?\n * @param pastures How many pastures to take into account.\n * @param aqueducts How many aqueducts to take into account\n * @returns The potential catnip per tick.\n */\n getPotentialCatnip(worstWeather, pastures, aqueducts) {\n let productionField = this._host.game.getEffect("catnipPerTickBase");\n if (worstWeather) {\n productionField *= 0.1;\n productionField *= 1 + this._host.game.getLimitedDR(this._host.game.getEffect("coldHarshness"), 1);\n } else {\n productionField *= this._host.game.calendar.getWeatherMod({ name: "catnip" }) + this._host.game.calendar.getCurSeason().modifiers.catnip;\n }\n if (this._host.game.science.getPolicy("communism").researched) {\n productionField = 0;\n }\n const resourceProduction = this._host.game.village.getResProduction();\n const productionVillager = resourceProduction.catnip ? resourceProduction.catnip * (1 + this._host.game.getEffect("catnipJobRatio")) : 0;\n let baseProd = productionField + productionVillager;\n let hydroponics = this._host.game.space.getBuilding("hydroponics").val;\n if (this._host.game.prestige.meta[0].meta[21].researched) {\n if (this._host.game.calendar.cycle === 2) {\n hydroponics *= 2;\n }\n if (this._host.game.calendar.cycle === 7) {\n hydroponics *= 0.5;\n }\n }\n baseProd *= 1 + 0.03 * aqueducts + 0.025 * hydroponics;\n const isWinterComing = this._host.game.challenges.currentChallenge === "winterIsComing";\n const paragonBonus = isWinterComing ? 0 : this._host.game.prestige.getParagonProductionRatio();\n baseProd *= 1 + paragonBonus;\n baseProd *= 1 + this._host.game.religion.getSolarRevolutionRatio();\n if (!this._host.game.opts.disableCMBR) {\n baseProd *= 1 + this._host.game.getCMBRBonus();\n }\n baseProd = mustExist(\n this._host.game.calendar.cycleEffectsFestival({ catnip: baseProd }).catnip\n );\n let baseDemand = this._host.game.village.getResConsumption().catnip;\n const unicornPastures = this._host.game.bld.getBuildingExt("unicornPasture").meta.val;\n baseDemand *= 1 + this._host.game.getLimitedDR(pastures * -5e-3 + unicornPastures * -15e-4, 1);\n if (this._host.game.village.sim.kittens.length > 0 && this._host.game.village.happiness > 1) {\n const happyCon = this._host.game.village.happiness - 1;\n const catnipDemandWorkerRatioGlobal = this._host.game.getEffect(\n "catnipDemandWorkerRatioGlobal"\n );\n if (this._host.game.challenges.currentChallenge === "anarchy") {\n baseDemand *= 1 + happyCon * (1 + catnipDemandWorkerRatioGlobal);\n } else {\n baseDemand *= 1 + happyCon * (1 + catnipDemandWorkerRatioGlobal) * (1 - this._host.game.village.getFreeKittens() / this._host.game.village.sim.kittens.length);\n }\n }\n baseProd += baseDemand;\n baseProd += this._host.game.getResourcePerTickConvertion("catnip");\n return baseProd;\n }\n /**\n * Maintains the CSS classes in the resource indicators in the game UI to\n * reflect if the amount of resource in stock is below or above the desired\n * total amount to keep in stock.\n * The user can configure this in the Workshop automation section.\n */\n refreshStock() {\n for (const [name, resource] of objectEntries(this._host.engine.settings.resources.resources)) {\n const resourceCells = [\n // Resource table on the top.\n ...$(`#game .res-row.resource_${name} .res-cell.resAmount`),\n // Craft table on the bottom.\n ...$(`#game .res-row.resource_${name} .res-cell.resource-value`)\n ];\n if (!resource.enabled || resource.stock === 0) {\n for (const resourceCell of resourceCells) {\n resourceCell.classList.remove("ks-stock-above", "ks-stock-below");\n }\n continue;\n }\n const isBelow = this._host.game.resPool.get(name).value < resource.stock;\n for (const resourceCell of resourceCells) {\n resourceCell.classList.add(isBelow ? "ks-stock-below" : "ks-stock-above");\n resourceCell.classList.remove(isBelow ? "ks-stock-above" : "ks-stock-below");\n }\n }\n }\n }\n __publicField(WorkshopManager, "DEFAULT_CONSUME_RATE", 1);\n class ResourcesSettingsItem extends Setting {\n constructor(resource, enabled = false, consume = WorkshopManager.DEFAULT_CONSUME_RATE, stock = 0) {\n super(enabled);\n __privateAdd(this, _resource2);\n __publicField(this, "consume");\n __publicField(this, "stock", 0);\n __privateSet(this, _resource2, resource);\n this.consume = consume;\n this.stock = stock;\n }\n get resource() {\n return __privateGet(this, _resource2);\n }\n }\n _resource2 = new WeakMap();\n class ResourcesSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "resources");\n this.resources = this.initResources();\n }\n initResources() {\n const items = {};\n for (const item of Resources) {\n items[item] = new ResourcesSettingsItem(item);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.resources, settings.resources, (resource, item) => {\n resource.enabled = (item == null ? void 0 : item.enabled) ?? resource.enabled;\n resource.consume = (item == null ? void 0 : item.consume) ?? resource.consume;\n resource.stock = (item == null ? void 0 : item.stock) ?? resource.stock;\n });\n }\n }\n class StateSettings extends Setting {\n constructor(noConfirm = new Setting(), compress = new Setting(true)) {\n super(true);\n __publicField(this, "noConfirm");\n __publicField(this, "compress");\n this.noConfirm = noConfirm;\n this.compress = compress;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n this.noConfirm.load(settings.noConfirm);\n this.compress.load(settings.compress);\n }\n }\n class EngineSettings extends Setting {\n constructor(enabled = false, filters = new LogFilterSettings(), resources = new ResourcesSettings(), states = new StateSettings(), language = FallbackLocale, ksColumn = new Setting()) {\n super(enabled);\n /**\n * The interval at which the internal processing loop is run, in milliseconds.\n */\n __publicField(this, "interval", 2e3);\n /**\n * The currently selected language.\n */\n __publicField(this, "locale");\n /**\n * Use a dedicated column in the UI for KS.\n */\n __publicField(this, "ksColumn");\n __publicField(this, "filters");\n __publicField(this, "resources");\n __publicField(this, "states");\n this.filters = filters;\n this.resources = resources;\n this.states = states;\n this.locale = new SettingOptions(language, [\n { label: "Deutsch", value: "de-DE" },\n { label: "English", value: "en-US" },\n { label: "עִברִית", value: "he-IL" },\n { label: "中文", value: "zh-CN" }\n ]);\n this.ksColumn = ksColumn;\n }\n load(settings, retainMetaBehavior = false) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n if (!retainMetaBehavior) {\n this.interval = settings.interval ?? this.interval;\n this.states.load(settings.states);\n this.locale.load(settings.locale);\n this.ksColumn.load(settings.ksColumn);\n }\n this.filters.load(settings.filters);\n this.resources.load(settings.resources);\n }\n }\n class ResetBonfireBuildingSetting extends SettingThreshold {\n constructor(building, enabled = false, threshold = -1, baseStage) {\n super(enabled, threshold);\n /**\n * In case this is an upgrade of another building, this is the name of the\n * base building.\n */\n __privateAdd(this, _baseBuilding2);\n __privateAdd(this, _building4);\n /**\n * In case this is an upgradable building, this indicates the level of\n * the stage.\n */\n __privateAdd(this, _stage2, 0);\n __privateSet(this, _building4, building);\n if (baseStage) {\n __privateSet(this, _stage2, 1);\n __privateSet(this, _baseBuilding2, baseStage);\n }\n }\n get baseBuilding() {\n return __privateGet(this, _baseBuilding2);\n }\n get building() {\n return __privateGet(this, _building4);\n }\n get stage() {\n return __privateGet(this, _stage2);\n }\n }\n _baseBuilding2 = new WeakMap();\n _building4 = new WeakMap();\n _stage2 = new WeakMap();\n class ResetBonfireSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "buildings");\n this.buildings = this.initBuildings();\n }\n initBuildings() {\n const baseStage = {\n broadcasttower: "amphitheatre",\n dataCenter: "library",\n hydroplant: "aqueduct",\n solarfarm: "pasture",\n spaceport: "warehouse"\n };\n const items = {};\n for (const item of Buildings) {\n if (item === "unicornPasture") {\n continue;\n }\n items[item] = new ResetBonfireBuildingSetting(item);\n }\n for (const item of StagedBuildings) {\n items[item] = new ResetBonfireBuildingSetting(item, false, -1, baseStage[item]);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n building.trigger = (item == null ? void 0 : item.trigger) ?? building.trigger;\n });\n }\n }\n class ResetReligionBuildingSetting extends SettingThreshold {\n constructor(building, variant, enabled = false, threshold = -1) {\n super(enabled, threshold);\n __privateAdd(this, _building5);\n __privateAdd(this, _variant3);\n __privateSet(this, _building5, building);\n __privateSet(this, _variant3, variant);\n }\n get building() {\n return __privateGet(this, _building5);\n }\n get variant() {\n return __privateGet(this, _variant3);\n }\n }\n _building5 = new WeakMap();\n _variant3 = new WeakMap();\n class ResetReligionSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "buildings");\n this.buildings = this.initBuildings();\n }\n initBuildings() {\n const items = {};\n for (const item of ReligionUpgrades) {\n items[item] = new ResetReligionBuildingSetting(item, UnicornItemVariant.OrderOfTheSun);\n }\n for (const item of TranscendenceUpgrades) {\n items[item] = new ResetReligionBuildingSetting(item, UnicornItemVariant.Cryptotheology);\n }\n for (const item of ZigguratUpgrades) {\n items[item] = new ResetReligionBuildingSetting(item, UnicornItemVariant.Ziggurat);\n }\n items.unicornPasture = new ResetReligionBuildingSetting(\n "unicornPasture",\n UnicornItemVariant.UnicornPasture\n );\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n building.trigger = (item == null ? void 0 : item.trigger) ?? building.trigger;\n });\n }\n }\n class ResetResourcesSettingsItem extends SettingThreshold {\n constructor(resource, enabled = false, threshold = -1) {\n super(enabled, threshold);\n __privateAdd(this, _resource3);\n __privateSet(this, _resource3, resource);\n }\n get resource() {\n return __privateGet(this, _resource3);\n }\n }\n _resource3 = new WeakMap();\n class ResetResourcesSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "resources");\n this.resources = this.initResources();\n }\n initResources() {\n const items = {};\n for (const item of Resources) {\n items[item] = new ResetResourcesSettingsItem(item);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.resources, settings.resources, (resource, item) => {\n resource.enabled = (item == null ? void 0 : item.enabled) ?? resource.enabled;\n resource.trigger = (item == null ? void 0 : item.trigger) ?? resource.trigger;\n });\n }\n }\n class ResetSpaceBuildingSetting extends SettingThreshold {\n constructor(building, enabled = false, threshold = -1) {\n super(enabled, threshold);\n __privateAdd(this, _building6);\n __privateSet(this, _building6, building);\n }\n get building() {\n return __privateGet(this, _building6);\n }\n }\n _building6 = new WeakMap();\n class ResetSpaceSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "buildings");\n this.buildings = this.initBuildings();\n }\n initBuildings() {\n const items = {};\n for (const item of SpaceBuildings) {\n items[item] = new ResetSpaceBuildingSetting(item);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n building.trigger = (item == null ? void 0 : item.trigger) ?? building.trigger;\n });\n }\n }\n class ResetTimeBuildingSetting extends SettingThreshold {\n constructor(id, variant, enabled = false, threshold = -1) {\n super(enabled, threshold);\n __privateAdd(this, _building7);\n __privateAdd(this, _variant4);\n __privateSet(this, _building7, id);\n __privateSet(this, _variant4, variant);\n }\n get building() {\n return __privateGet(this, _building7);\n }\n get variant() {\n return __privateGet(this, _variant4);\n }\n }\n _building7 = new WeakMap();\n _variant4 = new WeakMap();\n class ResetTimeSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "buildings");\n this.buildings = this.initBuildings();\n }\n initBuildings() {\n const items = {};\n for (const item of ChronoForgeUpgrades) {\n items[item] = new ResetTimeBuildingSetting(item, TimeItemVariant.Chronoforge);\n }\n for (const item of VoidSpaceUpgrades) {\n if (item === "usedCryochambers") {\n continue;\n }\n items[item] = new ResetTimeBuildingSetting(item, TimeItemVariant.VoidSpace);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n building.trigger = (item == null ? void 0 : item.trigger) ?? building.trigger;\n });\n }\n }\n class ResetUpgradeSettingsItem extends Setting {\n constructor(upgrade, enabled = false) {\n super(enabled);\n __privateAdd(this, _upgrade3);\n __privateSet(this, _upgrade3, upgrade);\n }\n get upgrade() {\n return __privateGet(this, _upgrade3);\n }\n }\n _upgrade3 = new WeakMap();\n class ResetUpgradeSettings extends Setting {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "upgrades");\n this.upgrades = this.initUpgrades();\n }\n initUpgrades() {\n const items = {};\n for (const item of Upgrades) {\n items[item] = new ResetUpgradeSettingsItem(item);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.upgrades, settings.upgrades, (upgrade, item) => {\n upgrade.enabled = (item == null ? void 0 : item.enabled) ?? upgrade.enabled;\n });\n }\n }\n class ResetSettings extends Setting {\n constructor(enabled = false, bonfire = new ResetBonfireSettings(), religion = new ResetReligionSettings(), resources = new ResetResourcesSettings(), space = new ResetSpaceSettings(), time = new ResetTimeSettings(), upgrades = new ResetUpgradeSettings()) {\n super(enabled);\n __publicField(this, "bonfire");\n __publicField(this, "religion");\n __publicField(this, "resources");\n __publicField(this, "space");\n __publicField(this, "time");\n __publicField(this, "upgrades");\n this.bonfire = bonfire;\n this.religion = religion;\n this.resources = resources;\n this.space = space;\n this.time = time;\n this.upgrades = upgrades;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n this.bonfire.load(settings.bonfire);\n this.religion.load(settings.religion);\n this.resources.load(settings.resources);\n this.space.load(settings.space);\n this.time.load(settings.time);\n this.upgrades.load(settings.upgrades);\n }\n }\n class TimeSkipHeatSettings extends SettingTrigger {\n constructor(activeHeatTransferStatus = new Setting()) {\n super(false, 1);\n __publicField(this, "cycles");\n __publicField(this, "activeHeatTransferStatus");\n this.cycles = this.initCycles();\n this.activeHeatTransferStatus = activeHeatTransferStatus;\n }\n initCycles() {\n const items = {};\n for (const item of Cycles) {\n items[item] = new Setting();\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.cycles, settings.cycles, (cycle, item) => {\n cycle.enabled = (item == null ? void 0 : item.enabled) ?? cycle.enabled;\n });\n this.activeHeatTransferStatus.load(settings.activeHeatTransferStatus);\n }\n }\n class TimeSkipSettings extends SettingThresholdMax {\n constructor(ignoreOverheat = new Setting(), activeHeatTransfer = new TimeSkipHeatSettings()) {\n super(false, 5);\n __publicField(this, "cycles");\n __publicField(this, "seasons");\n __publicField(this, "activeHeatTransfer");\n __publicField(this, "ignoreOverheat");\n this.cycles = this.initCycles();\n this.seasons = this.initSeason();\n this.activeHeatTransfer = activeHeatTransfer;\n this.ignoreOverheat = ignoreOverheat;\n }\n initCycles() {\n const items = {};\n for (const item of Cycles) {\n items[item] = new Setting();\n }\n return items;\n }\n initSeason() {\n const items = {};\n for (const item of Seasons) {\n items[item] = new Setting();\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.cycles, settings.cycles, (cycle, item) => {\n cycle.enabled = (item == null ? void 0 : item.enabled) ?? cycle.enabled;\n });\n consumeEntriesPedantic(this.seasons, settings.seasons, (season, item) => {\n season.enabled = (item == null ? void 0 : item.enabled) ?? season.enabled;\n });\n this.ignoreOverheat.load(settings.ignoreOverheat);\n this.activeHeatTransfer.load(settings.activeHeatTransfer);\n }\n }\n class TimeControlSettings extends Setting {\n constructor(enabled = false, accelerateTime = new SettingTrigger(false, 1), reset2 = new ResetSettings(), timeSkip = new TimeSkipSettings()) {\n super(enabled);\n __publicField(this, "accelerateTime");\n __publicField(this, "timeSkip");\n __publicField(this, "reset");\n this.accelerateTime = accelerateTime;\n this.reset = reset2;\n this.timeSkip = timeSkip;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n this.accelerateTime.load(settings.accelerateTime);\n this.reset.load(settings.reset);\n this.timeSkip.load(settings.timeSkip);\n }\n }\n class TimeSettingsItem extends SettingTriggerMax {\n constructor(building, variant, enabled = false) {\n super(enabled, -1, 0);\n __privateAdd(this, _building8);\n __privateAdd(this, _variant5);\n __privateSet(this, _building8, building);\n __privateSet(this, _variant5, variant);\n }\n get building() {\n return __privateGet(this, _building8);\n }\n get variant() {\n return __privateGet(this, _variant5);\n }\n }\n _building8 = new WeakMap();\n _variant5 = new WeakMap();\n class TimeSettings extends SettingTrigger {\n constructor(enabled = false, trigger = -1, fixCryochambers = new Setting()) {\n super(enabled, trigger);\n __publicField(this, "buildings");\n __publicField(this, "fixCryochambers");\n this.buildings = this.initBuildings();\n this.fixCryochambers = fixCryochambers;\n }\n initBuildings() {\n const items = {};\n for (const item of ChronoForgeUpgrades) {\n items[item] = new TimeSettingsItem(item, TimeItemVariant.Chronoforge);\n }\n for (const item of VoidSpaceUpgrades) {\n if (item === "usedCryochambers") {\n continue;\n }\n items[item] = new TimeSettingsItem(item, TimeItemVariant.VoidSpace);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.buildings, settings.buildings, (building, item) => {\n building.enabled = (item == null ? void 0 : item.enabled) ?? building.enabled;\n building.max = (item == null ? void 0 : item.max) ?? building.max;\n building.trigger = (item == null ? void 0 : item.trigger) ?? building.trigger;\n });\n this.fixCryochambers.load(settings.fixCryochambers);\n }\n }\n class EmbassySetting extends SettingMax {\n constructor(race, enabled = false) {\n super(enabled);\n __privateAdd(this, _race);\n __privateSet(this, _race, race);\n }\n get race() {\n return __privateGet(this, _race);\n }\n }\n _race = new WeakMap();\n class EmbassySettings extends SettingTrigger {\n constructor(enabled = false) {\n super(enabled);\n __publicField(this, "races");\n this.races = this.initRaces();\n }\n initRaces() {\n const items = {};\n for (const item of Races) {\n if (item === "leviathans") {\n continue;\n }\n items[item] = new EmbassySetting(item);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.races, settings.races, (race, item) => {\n race.enabled = (item == null ? void 0 : item.enabled) ?? race.enabled;\n race.max = (item == null ? void 0 : item.max) ?? race.max;\n });\n }\n }\n class TradeSettingsItem extends SettingLimitedTrigger {\n constructor(race, enabled, limited, summer, autumn, winter, spring, require2 = false) {\n super(enabled, limited);\n __privateAdd(this, _race2);\n __publicField(this, "seasons");\n /**\n * A resource that is required to trade with the race.\n */\n __privateAdd(this, _require);\n __privateSet(this, _race2, race);\n this.seasons = {\n autumn: new Setting(autumn),\n spring: new Setting(spring),\n summer: new Setting(summer),\n winter: new Setting(winter)\n };\n __privateSet(this, _require, require2);\n }\n get race() {\n return __privateGet(this, _race2);\n }\n get require() {\n return __privateGet(this, _require);\n }\n }\n _race2 = new WeakMap();\n _require = new WeakMap();\n class TradeSettings extends SettingTrigger {\n constructor(enabled = false, trigger = -1, buildEmbassies = new EmbassySettings(), feedLeviathans = new Setting(), tradeBlackcoin = new SettingBuySellThreshold(false, 1090, 1095, 1e4), unlockRaces = new Setting()) {\n super(enabled, trigger);\n __publicField(this, "races");\n __publicField(this, "feedLeviathans");\n __publicField(this, "buildEmbassies");\n __publicField(this, "tradeBlackcoin");\n __publicField(this, "unlockRaces");\n this.races = this.initRaces();\n this.buildEmbassies = buildEmbassies;\n this.feedLeviathans = feedLeviathans;\n this.tradeBlackcoin = tradeBlackcoin;\n this.unlockRaces = unlockRaces;\n }\n initRaces() {\n const defaultRequire = {\n dragons: "titanium",\n griffins: "wood",\n leviathans: "unobtainium",\n lizards: "minerals",\n sharks: "iron"\n };\n const items = {};\n for (const item of Races) {\n const require2 = defaultRequire[item] ?? false;\n items[item] = new TradeSettingsItem(item, false, false, false, false, false, false, require2);\n }\n return items;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.races, settings.races, (race, item) => {\n race.enabled = (item == null ? void 0 : item.enabled) ?? race.enabled;\n race.limited = (item == null ? void 0 : item.limited) ?? race.limited;\n race.trigger = (item == null ? void 0 : item.trigger) ?? race.trigger;\n race.seasons.autumn.enabled = (item == null ? void 0 : item.seasons.autumn.enabled) ?? race.seasons.autumn.enabled;\n race.seasons.spring.enabled = (item == null ? void 0 : item.seasons.spring.enabled) ?? race.seasons.spring.enabled;\n race.seasons.summer.enabled = (item == null ? void 0 : item.seasons.summer.enabled) ?? race.seasons.summer.enabled;\n race.seasons.winter.enabled = (item == null ? void 0 : item.seasons.winter.enabled) ?? race.seasons.winter.enabled;\n });\n this.buildEmbassies.load(settings.buildEmbassies);\n this.feedLeviathans.load(settings.feedLeviathans);\n this.tradeBlackcoin.load(settings.tradeBlackcoin);\n this.unlockRaces.load(settings.unlockRaces);\n }\n }\n class ElectLeaderSettings extends Setting {\n constructor(enabled = false, job = new SettingOptions(\n "any",\n Jobs.map((item) => {\n return { label: "", value: item };\n })\n ), trait = new SettingOptions(\n "none",\n Traits.map((item) => {\n return { label: "", value: item };\n })\n )) {\n super(enabled);\n __publicField(this, "job");\n __publicField(this, "trait");\n this.job = job;\n this.trait = trait;\n }\n load(settings) {\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n this.job.load(settings.job);\n this.trait.load(settings.trait);\n }\n }\n class VillageSettings extends Setting {\n constructor(enabled = false, holdFestivals = new Setting(), hunt = new SettingTrigger(false, 0.98), promoteKittens = new SettingTrigger(false, 1), promoteLeader = new Setting(), electLeader = new ElectLeaderSettings()) {\n super(enabled);\n __publicField(this, "jobs");\n __publicField(this, "holdFestivals");\n __publicField(this, "hunt");\n __publicField(this, "promoteKittens");\n __publicField(this, "promoteLeader");\n __publicField(this, "electLeader");\n this.jobs = this.initJobs();\n this.holdFestivals = holdFestivals;\n this.hunt = hunt;\n this.promoteKittens = promoteKittens;\n this.promoteLeader = promoteLeader;\n this.electLeader = electLeader;\n }\n initJobs() {\n const items = {};\n for (const item of Jobs) {\n items[item] = new SettingMax(false, 0);\n }\n return items;\n }\n load(settings) {\n var _a, _b, _c;\n if (isNil(settings)) {\n return;\n }\n super.load(settings);\n consumeEntriesPedantic(this.jobs, settings.jobs, (job, item) => {\n job.enabled = (item == null ? void 0 : item.enabled) ?? job.enabled;\n job.max = (item == null ? void 0 : item.max) ?? job.max;\n });\n this.holdFestivals.enabled = ((_a = settings.holdFestivals) == null ? void 0 : _a.enabled) ?? this.holdFestivals.enabled;\n this.hunt.load(settings.hunt);\n this.promoteKittens.enabled = ((_b = settings.promoteKittens) == null ? void 0 : _b.enabled) ?? this.promoteKittens.enabled;\n this.promoteLeader.enabled = ((_c = settings.promoteLeader) == null ? void 0 : _c.enabled) ?? this.promoteLeader.enabled;\n this.electLeader.load(settings.electLeader);\n }\n }\n class TimeControlManager {\n constructor(host, bonfireManager, religionManager, spaceManager, workshopManager, settings = new TimeControlSettings()) {\n __publicField(this, "_host");\n __publicField(this, "settings");\n __publicField(this, "manager");\n __publicField(this, "_bonfireManager");\n __publicField(this, "_religionManager");\n __publicField(this, "_spaceManager");\n __publicField(this, "_workshopManager");\n this._host = host;\n this.settings = settings;\n this.manager = new TabManager(this._host, "Time");\n this._bonfireManager = bonfireManager;\n this._religionManager = religionManager;\n this._spaceManager = spaceManager;\n this._workshopManager = workshopManager;\n }\n async tick(_context) {\n if (!this.settings.enabled) {\n return;\n }\n if (this.settings.accelerateTime.enabled) {\n this.accelerateTime();\n }\n if (this.settings.timeSkip.enabled) {\n this.timeSkip();\n }\n if (this.settings.reset.enabled) {\n await this.autoReset(this._host.engine);\n }\n }\n async autoReset(engine) {\n if (this._host.game.challenges.currentChallenge) {\n return;\n }\n const checkedList = [];\n const checkList = [];\n const check = (buttons) => {\n if (checkList.length !== 0) {\n for (const button2 of buttons) {\n if (isNil(button2.model)) {\n continue;\n }\n const model = button2.model;\n const name = model.metadata.name;\n const index = checkList.indexOf(name);\n if (index !== -1) {\n checkList.splice(index, 1);\n if (this._host.game.resPool.hasRes(mustExist(model.prices))) {\n return true;\n }\n }\n }\n }\n return false;\n };\n for (const [name, entry] of objectEntries(this.settings.reset.bonfire.buildings)) {\n if (!entry.enabled) {\n continue;\n }\n if (entry.trigger < 0) {\n return;\n }\n let bld;\n try {\n bld = this._host.game.bld.getBuildingExt(name);\n } catch (_error) {\n bld = null;\n }\n if (isNil(bld)) {\n continue;\n }\n checkedList.push({\n name: bld.meta.label ?? mustExist(bld.meta.stages)[mustExist(bld.meta.stage)].label,\n trigger: entry.trigger,\n val: bld.meta.val\n });\n if (0 < entry.trigger) {\n if (bld.meta.val < entry.trigger) {\n return;\n }\n } else {\n checkList.push(name);\n }\n }\n const unicornPasture = this.settings.reset.religion.buildings.unicornPasture;\n if (unicornPasture.enabled) {\n if (unicornPasture.trigger < 0) {\n return;\n }\n const bld = this._host.game.bld.getBuildingExt("unicornPasture");\n checkedList.push({\n name: mustExist(bld.meta.label),\n trigger: unicornPasture.trigger,\n val: bld.meta.val\n });\n if (0 < unicornPasture.trigger) {\n if (bld.meta.val < unicornPasture.trigger) {\n return;\n }\n } else {\n checkList.push("unicornPasture");\n }\n }\n if (check(this._bonfireManager.manager.tab.children) || checkList.length) {\n return;\n }\n for (const [name, entry] of objectEntries(this.settings.reset.space.buildings)) {\n if (!entry.enabled) {\n continue;\n }\n if (entry.trigger < 0) {\n return;\n }\n const bld = this._host.game.space.getBuilding(name);\n checkedList.push({ name: bld.label, trigger: entry.trigger, val: bld.val });\n if (0 < entry.trigger) {\n if (bld.val < entry.trigger) {\n return;\n }\n } else {\n checkList.push(name);\n }\n }\n if (checkList.length === 0) {\n const panels = mustExist(this._spaceManager.manager.tab.planetPanels);\n for (const panel of panels) {\n for (const panelButton of panel.children) {\n const model = mustExist(panelButton.model);\n const name = model.metadata.name;\n const index = checkList.indexOf(name);\n if (index !== -1) {\n checkList.splice(index, 1);\n if (this._host.game.resPool.hasRes(mustExist(model.prices))) {\n break;\n }\n }\n }\n }\n }\n if (checkList.length) {\n return;\n }\n for (const [name, entry] of objectEntries(this.settings.reset.religion.buildings)) {\n if (!entry.enabled) {\n continue;\n }\n if (entry.trigger < 0) {\n return;\n }\n const bld = mustExist(this._religionManager.getBuild(name, entry.variant));\n checkedList.push({ name: bld.label, trigger: entry.trigger, val: bld.val });\n if (0 < entry.trigger) {\n if (bld.val < entry.trigger) {\n return;\n }\n } else {\n checkList.push(name);\n }\n }\n if (\n // @ts-expect-error The `check()` calls are unsafe and need to be rewritten.\n check(this._religionManager.manager.tab.zgUpgradeButtons) || // @ts-expect-error The `check()` calls are unsafe and need to be rewritten.\n check(this._religionManager.manager.tab.rUpgradeButtons) || // @ts-expect-error The `check()` calls are unsafe and need to be rewritten.\n check(this._religionManager.manager.tab.ctPanel.children[0].children) || checkList.length\n ) {\n return;\n }\n for (const [name, entry] of objectEntries(this.settings.reset.time.buildings)) {\n if (!entry.enabled) {\n continue;\n }\n if (entry.trigger < 0) {\n return;\n }\n const bld = mustExist(this.getBuild(name, entry.variant));\n checkedList.push({ name: bld.label, trigger: entry.trigger, val: bld.val });\n if (0 < entry.trigger) {\n if (bld.val < entry.trigger) {\n return;\n }\n } else {\n checkList.push(name);\n }\n }\n if (\n // @ts-expect-error The `check()` calls are unsafe and need to be rewritten.\n check(this.manager.tab.cfPanel.children[0].children) || // @ts-expect-error The `check()` calls are unsafe and need to be rewritten.\n check(this.manager.tab.vsPanel.children[0].children) || checkList.length\n ) {\n return;\n }\n for (const [name, entry] of objectEntries(this.settings.reset.resources.resources)) {\n if (!entry.enabled) {\n continue;\n }\n if (entry.trigger < 0) {\n return;\n }\n const res = mustExist(this._host.game.resPool.get(name));\n checkedList.push({\n name: this._host.engine.i18n(`$resources.${entry.resource}.title`),\n trigger: entry.trigger,\n val: res.value\n });\n if (res.value < entry.trigger) {\n return;\n }\n }\n for (const [, entry] of objectEntries(this.settings.reset.upgrades.upgrades)) {\n if (entry.enabled) {\n const upgrade = mustExist(\n this._host.game.workshop.upgrades.find((subject) => subject.name === entry.upgrade)\n );\n checkedList.push({ name: upgrade.label, trigger: 1, val: upgrade.researched ? 1 : 0 });\n if (!upgrade.researched) {\n return;\n }\n }\n }\n engine.stop(false);\n const sleep2 = async (time = 1500) => {\n return new Promise((resolve, reject) => {\n if (!this._host.engine.settings.enabled) {\n reject(new Error("canceled by player"));\n return;\n }\n setTimeout(resolve, time);\n });\n };\n try {\n for (const checked2 of checkedList) {\n await sleep2(500);\n this._host.engine.imessage("reset.check", [\n checked2.name,\n this._host.game.getDisplayValueExt(checked2.trigger),\n this._host.game.getDisplayValueExt(checked2.val)\n ]);\n }\n await sleep2(0);\n this._host.engine.imessage("reset.checked");\n await sleep2();\n this._host.engine.iactivity("reset.tip");\n await sleep2();\n this._host.engine.imessage("reset.countdown.10");\n await sleep2(2e3);\n this._host.engine.imessage("reset.countdown.9");\n await sleep2();\n this._host.engine.imessage("reset.countdown.8");\n await sleep2();\n this._host.engine.imessage("reset.countdown.7");\n await sleep2();\n this._host.engine.imessage("reset.countdown.6");\n await sleep2();\n this._host.engine.imessage("reset.countdown.5");\n await sleep2();\n this._host.engine.imessage("reset.countdown.4");\n await sleep2();\n this._host.engine.imessage("reset.countdown.3");\n await sleep2();\n this._host.engine.imessage("reset.countdown.2");\n await sleep2();\n this._host.engine.imessage("reset.countdown.1");\n await sleep2();\n this._host.engine.imessage("reset.countdown.0");\n await sleep2();\n this._host.engine.iactivity("reset.last.message");\n await sleep2();\n } catch (_error) {\n this._host.engine.imessage("reset.cancel.message");\n this._host.engine.iactivity("reset.cancel.activity");\n return;\n }\n for (let challengeIndex = 0; challengeIndex < this._host.game.challenges.challenges.length; challengeIndex++) {\n this._host.game.challenges.challenges[challengeIndex].pending = false;\n }\n this._host.game.resetAutomatic();\n }\n accelerateTime() {\n const temporalFluxAvailable = this._workshopManager.getValueAvailable("temporalFlux");\n if (temporalFluxAvailable <= 0) {\n if (this._host.game.time.isAccelerated) {\n this._host.game.time.isAccelerated = false;\n }\n return;\n }\n if (this._host.game.time.isAccelerated) {\n return;\n }\n const temporalFlux = this._host.game.resPool.get("temporalFlux");\n if (temporalFlux.maxValue * this.settings.accelerateTime.trigger <= temporalFlux.value) {\n this._host.game.time.isAccelerated = true;\n this._host.engine.iactivity("act.accelerate", [], "ks-accelerate");\n this._host.engine.storeForSummary("accelerate", 1);\n }\n }\n timeSkip() {\n if (!this._host.game.workshop.get("chronoforge").researched) {\n return;\n }\n if (this._host.game.calendar.day < 0) {\n return;\n }\n const shatterCostIncreaseChallenge = this._host.game.getEffect("shatterCostIncreaseChallenge");\n const timeCrystalsAvailable = this._workshopManager.getValueAvailable("timeCrystal");\n if (timeCrystalsAvailable < this.settings.timeSkip.trigger || timeCrystalsAvailable < 1 + shatterCostIncreaseChallenge) {\n return;\n }\n const shatterVoidCost = this._host.game.getEffect("shatterVoidCost");\n const voidAvailable = this._workshopManager.getValueAvailable("void");\n if (voidAvailable < shatterVoidCost) {\n return;\n }\n const season = this._host.game.calendar.season;\n if (!this.settings.timeSkip.seasons[this._host.game.calendar.seasons[season].name].enabled) {\n return;\n }\n const currentCycle = this._host.game.calendar.cycle;\n if (!this.settings.timeSkip.cycles[Cycles[currentCycle]].enabled) {\n return;\n }\n const heatMax = this._host.game.getEffect("heatMax");\n const heatNow = this._host.game.time.heat;\n if (!this.settings.timeSkip.ignoreOverheat.enabled) {\n if (heatMax <= heatNow) {\n return;\n }\n }\n const factor = this._host.game.challenges.getChallenge("1000Years").researched ? 5 : 10;\n let maxSkipsActiveHeatTransfer = Number.POSITIVE_INFINITY;\n if (!this.settings.timeSkip.ignoreOverheat.enabled && this.settings.timeSkip.activeHeatTransfer.enabled) {\n const heatPerTick = this._host.game.getEffect("heatPerTick");\n const ticksPerSecond = this._host.game.ticksPerSecond;\n if (this.settings.timeSkip.activeHeatTransfer.activeHeatTransferStatus.enabled) {\n if (heatNow <= heatMax * this.settings.timeSkip.activeHeatTransfer.trigger) {\n this.settings.timeSkip.activeHeatTransfer.activeHeatTransferStatus.enabled = false;\n this._host.refreshEntireUserInterface();\n this._host.engine.iactivity("act.time.activeHeatTransferEnd", [], "ks-timeSkip");\n }\n const temporalFluxProduction = this._host.game.getEffect("temporalFluxProduction");\n const daysPerYear = (this._host.game.calendar.daysPerSeason + 10 + this._host.game.getEffect("temporalParadoxDay")) * this._host.game.calendar.seasonsPerYear;\n const ticksPerDay = this._host.game.calendar.ticksPerDay;\n const daysPerTicks = (1 + this._host.game.timeAccelerationRatio()) / ticksPerDay;\n const ticksPerYear = daysPerYear / daysPerTicks;\n const temporalFlux = this._host.game.resPool.get("temporalFlux");\n const fluxEnabled = temporalFlux.maxValue > ticksPerYear;\n const flux = temporalFlux.value < ticksPerYear;\n if (!season && this._host.game.calendar.day < 10 && temporalFluxProduction > factor / heatPerTick && this.settings.accelerateTime.enabled && fluxEnabled && flux) {\n maxSkipsActiveHeatTransfer = Math.ceil(\n (ticksPerYear + ticksPerDay * 10 - temporalFlux.value) / temporalFluxProduction\n );\n this._host.engine.iactivity("act.time.getTemporalFlux", [], "ks-timeSkip");\n this._host.engine.storeForSummary("time.getTemporalFlux", 1);\n } else if (this.settings.timeSkip.activeHeatTransfer.cycles[Cycles[currentCycle]].enabled) {\n return;\n } else {\n maxSkipsActiveHeatTransfer = this._host.game.calendar.yearsPerCycle - this._host.game.calendar.cycleYear;\n }\n } else if (heatNow >= heatMax - heatPerTick * ticksPerSecond * 10) {\n this.settings.timeSkip.activeHeatTransfer.activeHeatTransferStatus.enabled = true;\n this._host.refreshEntireUserInterface();\n this._host.engine.iactivity("act.time.activeHeatTransferStart", [], "ks-timeSkip");\n this._host.engine.storeForSummary("time.activeHeatTransferStart", 1);\n }\n }\n const maxSkips = negativeOneToInfinity(this.settings.timeSkip.max);\n let canSkip = Math.floor(\n Math.min(\n this.settings.timeSkip.ignoreOverheat.enabled ? Number.POSITIVE_INFINITY : (heatMax - heatNow) / factor,\n maxSkips,\n maxSkipsActiveHeatTransfer,\n timeCrystalsAvailable / (1 + shatterCostIncreaseChallenge),\n 0 < shatterVoidCost ? voidAvailable / shatterVoidCost : Number.POSITIVE_INFINITY\n )\n );\n let willSkip = 0;\n const yearsPerCycle = this._host.game.calendar.yearsPerCycle;\n const remainingYearsCurrentCycle = yearsPerCycle - this._host.game.calendar.cycleYear;\n const cyclesPerEra = this._host.game.calendar.cyclesPerEra;\n if (canSkip < remainingYearsCurrentCycle) {\n willSkip = canSkip;\n } else {\n willSkip += remainingYearsCurrentCycle;\n canSkip -= remainingYearsCurrentCycle;\n let skipCycles = 1;\n while (yearsPerCycle < canSkip && this.settings.timeSkip.cycles[Cycles[(currentCycle + skipCycles) % cyclesPerEra]].enabled) {\n willSkip += yearsPerCycle;\n canSkip -= yearsPerCycle;\n skipCycles += 1;\n }\n if (this.settings.timeSkip.cycles[Cycles[(currentCycle + skipCycles) % cyclesPerEra]].enabled && 0 < canSkip) {\n willSkip += canSkip;\n }\n }\n if (0 < willSkip) {\n const shatter = this._host.game.timeTab.cfPanel.children[0].children[0];\n if (isNil(shatter.model)) {\n return;\n }\n this._host.engine.iactivity("act.time.skip", [willSkip], "ks-timeSkip");\n shatter.controller.doShatterAmt(shatter.model, willSkip);\n this._host.engine.storeForSummary("time.skip", willSkip);\n }\n }\n getBuild(name, variant) {\n if (variant === TimeItemVariant.Chronoforge) {\n return this._host.game.time.getCFU(name);\n }\n return this._host.game.time.getVSU(name);\n }\n }\n class TimeManager {\n constructor(host, workshopManager, settings = new TimeSettings()) {\n __publicField(this, "_host");\n __publicField(this, "settings");\n __publicField(this, "manager");\n __publicField(this, "_bulkManager");\n __publicField(this, "_workshopManager");\n this._host = host;\n this.settings = settings;\n this.manager = new TabManager(this._host, "Time");\n this._bulkManager = new BulkPurchaseHelper(this._host, workshopManager);\n this._workshopManager = workshopManager;\n }\n tick(context) {\n if (!this.settings.enabled) {\n return;\n }\n this.manager.render();\n this.autoBuild(context);\n if (this.settings.fixCryochambers.enabled) {\n this.fixCryochambers();\n }\n }\n /**\n * Try to build as many of the passed buildings as possible.\n * Usually, this is called at each iteration of the automation engine to\n * handle the building of items on the Time tab.\n *\n * @param builds The buildings to build.\n */\n autoBuild(context, builds = this.settings.buildings) {\n const bulkManager = this._bulkManager;\n const sectionTrigger = this.settings.trigger;\n const metaData = {};\n for (const build of Object.values(builds)) {\n const buildMeta = this.getBuild(build.building, build.variant);\n metaData[build.building] = mustExist(buildMeta);\n const buildButton = build.variant === TimeItemVariant.Chronoforge ? this._getBuildButtonCF(build.building) : this._getBuildButtonVS(build.building);\n if (isNil(buildButton)) {\n continue;\n }\n const model = buildButton.model;\n const panel = build.variant === TimeItemVariant.Chronoforge ? this.manager.tab.cfPanel : this.manager.tab.vsPanel;\n const buildingMetaData = mustExist(metaData[build.building]);\n buildingMetaData.tHidden = !(model == null ? void 0 : model.visible) || !model.enabled || !panel.visible;\n }\n const buildList = bulkManager.bulk(builds, metaData, sectionTrigger, "Time");\n for (const build of buildList) {\n if (build.count > 0) {\n this.build(\n build.id,\n build.variant,\n build.count\n );\n context.requestGameUiRefresh = true;\n }\n }\n }\n build(name, variant, amount) {\n let amountCalculated = amount;\n let label2;\n const amountTemp = amountCalculated;\n if (variant === TimeItemVariant.Chronoforge) {\n const itemMetaRaw = game.getUnlockByName(name, "chronoforge");\n const controller = new classes.ui.time.ChronoforgeBtnController(\n this._host.game\n );\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);\n label2 = itemMetaRaw.label;\n } else {\n const itemMetaRaw = game.getUnlockByName(name, "voidSpace");\n const controller = new classes.ui.time.VoidSpaceBtnController(\n this._host.game\n );\n const model = controller.fetchModel({ controller, id: itemMetaRaw.name });\n amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);\n label2 = itemMetaRaw.label;\n }\n if (amountCalculated !== amountTemp) {\n console.warn(\n ...cl(`${label2} Amount ordered: ${amountTemp} Amount Constructed: ${amountCalculated}`)\n );\n if (amountCalculated === 0) {\n return;\n }\n }\n this._host.engine.storeForSummary(label2, amountCalculated, "build");\n if (amountCalculated === 1) {\n this._host.engine.iactivity("act.build", [label2], "ks-build");\n } else {\n this._host.engine.iactivity(\n "act.builds",\n [label2, this._host.renderAbsolute(amountCalculated)],\n "ks-build"\n );\n }\n }\n getBuild(name, variant) {\n if (variant === TimeItemVariant.Chronoforge) {\n return this._host.game.time.getCFU(name);\n }\n return this._host.game.time.getVSU(name);\n }\n _getBuildButtonCF(name) {\n return this.manager.tab.children[2].children[0].children.find((button2) => button2.id === name) ?? null;\n }\n _getBuildButtonVS(name) {\n return this.manager.tab.children[3].children[0].children.find((button2) => button2.id === name) ?? null;\n }\n fixCryochambers() {\n if (this._host.game.time.getVSU("usedCryochambers").val < 1) {\n return;\n }\n const prices = mustExist(this._host.game.time.getVSU("usedCryochambers").fixPrices);\n for (const price of prices) {\n const available = this._workshopManager.getValueAvailable(price.name);\n if (available < price.val) {\n return;\n }\n }\n const btn = this.manager.tab.vsPanel.children[0].children[0];\n let fixed = 0;\n let fixHappened;\n do {\n fixHappened = false;\n const buyResult = btn.controller.buyItem(mustExist(btn.model), new MouseEvent("click"));\n fixHappened = buyResult.itemBought;\n fixed += fixHappened ? 1 : 0;\n } while (fixHappened);\n if (0 < fixed) {\n this._host.engine.iactivity("act.fix.cry", [this._host.renderAbsolute(fixed)], "ks-fixCry");\n this._host.engine.storeForSummary("fix.cry", fixed);\n }\n }\n }\n class TradeManager {\n constructor(host, workshopManager, settings = new TradeSettings()) {\n __publicField(this, "_host");\n __publicField(this, "settings");\n __publicField(this, "manager");\n __publicField(this, "_workshopManager");\n this._host = host;\n this.settings = settings;\n this.manager = new TabManager(this._host, "Trade");\n this._workshopManager = workshopManager;\n }\n tick(context) {\n if (!this.settings.enabled) {\n return;\n }\n this.manager.render();\n this.autoTrade();\n if (this.settings.unlockRaces.enabled) {\n this.autoUnlock(context);\n }\n if (this.settings.buildEmbassies.enabled) {\n this.autoBuildEmbassies(context);\n }\n if (this.settings.feedLeviathans.enabled) {\n this.autoFeedElders();\n }\n if (this.settings.tradeBlackcoin.enabled) {\n this.autoTradeBlackcoin();\n }\n }\n autoTrade(cacheManager) {\n var _a;\n const catpower = this._workshopManager.getResource("manpower");\n const gold = this._workshopManager.getResource("gold");\n const sectionTrigger = this.settings.trigger;\n const trades = [];\n const season = this._host.game.calendar.getCurSeason().name;\n for (const trade of Object.values(this.settings.races)) {\n const race = this.getRace(trade.race);\n const trigger = Engine.evaluateSubSectionTrigger(sectionTrigger, trade.trigger);\n if (trigger < 0 || !trade.enabled || !trade.seasons[season].enabled || !race.unlocked || !this.singleTradePossible(sectionTrigger, catpower, gold, trade)) {\n continue;\n }\n const button2 = this.getTradeButton(race.name);\n if (!((_a = button2 == null ? void 0 : button2.model) == null ? void 0 : _a.enabled)) {\n continue;\n }\n const require2 = trade.require ? this._workshopManager.getResource(trade.require) : false;\n const profitable = this.getProfitability(trade.race);\n if (trade.limited && profitable) {\n trades.push(trade.race);\n } else if (\n // If this trade is not limited, it must either not require anything, or\n // the required resource must be over the trigger value.\n // Additionally, gold must also be over the trigger value.\n !require2 || trigger <= require2.value / require2.maxValue\n ) {\n trades.push(trade.race);\n }\n }\n if (trades.length === 0) {\n return;\n }\n let maxTrades = this.getLowestTradeAmount(null, true, false);\n if (maxTrades < 1) {\n return;\n }\n const maxByRace = [];\n for (let tradeIndex = 0; tradeIndex < trades.length; tradeIndex++) {\n const race = trades[tradeIndex];\n const tradeSettings = this.settings.races[race];\n const require2 = !tradeSettings.require ? false : this._workshopManager.getResource(tradeSettings.require);\n const trigger = Engine.evaluateSubSectionTrigger(sectionTrigger, tradeSettings.trigger);\n const trigConditions = (!require2 || trigger <= require2.value / require2.maxValue) && trigger <= gold.value / gold.maxValue;\n const tradePos = this.getLowestTradeAmount(race, tradeSettings.limited, trigConditions);\n if (tradePos < 1) {\n trades.splice(tradeIndex, 1);\n tradeIndex--;\n continue;\n }\n maxByRace.push(tradePos);\n }\n if (trades.length === 0) {\n return;\n }\n const tradesDone = {};\n while (0 < trades.length && 1 <= maxTrades) {\n if (maxTrades < trades.length) {\n const randomRaceIndex = Math.floor(Math.random() * trades.length);\n const tradeIndex2 = trades[randomRaceIndex];\n if (isNil(tradesDone[tradeIndex2])) {\n tradesDone[tradeIndex2] = 0;\n }\n tradesDone[tradeIndex2] += 1;\n maxTrades -= 1;\n trades.splice(randomRaceIndex, 1);\n maxByRace.splice(randomRaceIndex, 1);\n continue;\n }\n let minTrades = Math.floor(maxTrades / trades.length);\n let minTradeIndex = 0;\n const tradeIndex = trades[minTradeIndex];\n for (let tradeIndex2 = 0; tradeIndex2 < trades.length; ++tradeIndex2) {\n if (maxByRace[tradeIndex2] < minTrades) {\n minTrades = maxByRace[tradeIndex2];\n minTradeIndex = tradeIndex2;\n }\n }\n if (isNil(tradesDone[tradeIndex])) {\n tradesDone[tradeIndex] = 0;\n }\n tradesDone[tradeIndex] += minTrades;\n maxTrades -= minTrades;\n trades.splice(minTradeIndex, 1);\n maxByRace.splice(minTradeIndex, 1);\n }\n if (Object.values(tradesDone).length === 0) {\n return;\n }\n const tradeNet = {};\n for (const [name, amount] of objectEntries(tradesDone)) {\n const race = this.getRace(name);\n const materials = this.getMaterials(name);\n for (const [mat, matAmount] of objectEntries(materials)) {\n if (!tradeNet[mat]) {\n tradeNet[mat] = 0;\n }\n tradeNet[mat] -= matAmount * amount;\n }\n const meanOutput = this.getAverageTrade(race);\n for (const [out, outValue] of objectEntries(meanOutput)) {\n const res = this._workshopManager.getResource(out);\n if (!tradeNet[out]) {\n tradeNet[out] = 0;\n }\n tradeNet[out] += res.maxValue > 0 ? Math.min(\n mustExist(meanOutput[out]) * mustExist(tradesDone[name]),\n Math.max(res.maxValue - res.value, 0)\n ) : outValue * mustExist(tradesDone[name]);\n }\n }\n if (!isNil(cacheManager)) {\n cacheManager.pushToCache({\n materials: tradeNet,\n timeStamp: this._host.game.timer.ticksTotal\n });\n }\n for (const [name, count] of objectEntries(tradesDone)) {\n if (0 < count) {\n this.trade(name, count);\n }\n }\n }\n autoBuildEmbassies(context) {\n var _a;\n if (!this._host.game.diplomacy.races[0].embassyPrices) {\n return;\n }\n const culture = this._workshopManager.getResource("culture");\n let cultureVal = 0;\n const trigger = this.settings.buildEmbassies.trigger;\n if (culture.value / culture.maxValue < negativeOneToInfinity(trigger)) {\n return;\n }\n const racePanels = this._host.game.diplomacyTab.racePanels;\n cultureVal = this._workshopManager.getValueAvailable("culture");\n const embassyBulk = {};\n const bulkTracker = [];\n for (let panelIndex = 0; panelIndex < racePanels.length; panelIndex++) {\n if (!racePanels[panelIndex].embassyButton) {\n continue;\n }\n const name = racePanels[panelIndex].race.name;\n const race = this._host.game.diplomacy.get(name);\n const max = negativeOneToInfinity(this.settings.buildEmbassies.races[name].max);\n if (!this.settings.buildEmbassies.races[name].enabled || max <= race.embassyLevel || !race.unlocked) {\n continue;\n }\n embassyBulk[name] = {\n basePrice: mustExist((_a = race.embassyPrices) == null ? void 0 : _a[0]).val,\n currentEm: race.embassyLevel,\n max,\n priceSum: 0,\n race,\n val: 0\n };\n bulkTracker.push(name);\n }\n if (bulkTracker.length === 0) {\n return;\n }\n while (bulkTracker.length > 0) {\n for (let raceIndex = 0; raceIndex < bulkTracker.length; raceIndex++) {\n const name = bulkTracker[raceIndex];\n const emBulk = mustExist(embassyBulk[name]);\n if (emBulk.max <= emBulk.currentEm + emBulk.val) {\n bulkTracker.splice(raceIndex, 1);\n --raceIndex;\n continue;\n }\n const nextPrice = emBulk.basePrice * 1.15 ** (emBulk.currentEm + emBulk.val);\n if (nextPrice <= cultureVal) {\n cultureVal -= nextPrice;\n emBulk.priceSum += nextPrice;\n emBulk.val += 1;\n context.requestGameUiRefresh = true;\n } else {\n bulkTracker.splice(raceIndex, 1);\n --raceIndex;\n }\n }\n }\n for (const [, emBulk] of objectEntries(embassyBulk)) {\n if (emBulk.val === 0) {\n continue;\n }\n cultureVal = this._workshopManager.getValueAvailable("culture");\n if (cultureVal < emBulk.priceSum) {\n console.warn(...cl("Something has gone horribly wrong.", emBulk.priceSum, cultureVal));\n }\n this._workshopManager.getResource("culture").value -= emBulk.priceSum;\n emBulk.race.embassyLevel += emBulk.val;\n this._host.engine.storeForSummary("embassy", emBulk.val);\n if (emBulk.val !== 1) {\n this._host.engine.iactivity("build.embassies", [emBulk.val, emBulk.race.title], "ks-build");\n } else {\n this._host.engine.iactivity("build.embassy", [emBulk.val, emBulk.race.title], "ks-build");\n }\n }\n }\n autoFeedElders() {\n const leviathanInfo = this._host.game.diplomacy.get("leviathans");\n const necrocorns = this._host.game.resPool.get("necrocorn");\n if (!leviathanInfo.unlocked || necrocorns.value === 0) {\n return;\n }\n if (1 <= necrocorns.value) {\n if (leviathanInfo.energy < this._host.game.diplomacy.getMarkerCap()) {\n this._host.game.diplomacy.feedElders();\n this._host.engine.iactivity("act.feed");\n this._host.engine.storeForSummary("feed", 1);\n }\n } else {\n if (0.25 * (1 + this._host.game.getEffect("corruptionBoostRatio")) < 1) {\n this._host.engine.storeForSummary("feed", necrocorns.value);\n this._host.game.diplomacy.feedElders();\n this._host.engine.iactivity("dispose.necrocorn");\n }\n }\n }\n autoUnlock(context) {\n if (!this._host.game.tabs[4].visible) {\n return;\n }\n const maxRaces = this._host.game.diplomacy.get("leviathans").unlocked ? 8 : 7;\n if (this._host.game.diplomacyTab.racePanels.length < maxRaces) {\n let manpower = this._workshopManager.getValueAvailable("manpower");\n if (!this._host.game.diplomacy.get("lizards").unlocked) {\n if (manpower >= 1e3) {\n this._host.game.resPool.get("manpower").value -= 1e3;\n const unlockedRace = mustExist(this._host.game.diplomacy.unlockRandomRace());\n this._host.engine.iactivity("upgrade.race", [unlockedRace.title], "ks-upgrade");\n manpower -= 1e3;\n context.requestGameUiRefresh = true;\n }\n }\n if (!this._host.game.diplomacy.get("sharks").unlocked) {\n if (manpower >= 1e3) {\n this._host.game.resPool.get("manpower").value -= 1e3;\n const unlockedRace = mustExist(this._host.game.diplomacy.unlockRandomRace());\n this._host.engine.iactivity("upgrade.race", [unlockedRace.title], "ks-upgrade");\n manpower -= 1e3;\n context.requestGameUiRefresh = true;\n }\n }\n if (!this._host.game.diplomacy.get("griffins").unlocked) {\n if (manpower >= 1e3) {\n this._host.game.resPool.get("manpower").value -= 1e3;\n const unlockedRace = mustExist(this._host.game.diplomacy.unlockRandomRace());\n this._host.engine.iactivity("upgrade.race", [unlockedRace.title], "ks-upgrade");\n manpower -= 1e3;\n context.requestGameUiRefresh = true;\n }\n }\n if (!this._host.game.diplomacy.get("nagas").unlocked && this._host.game.resPool.get("culture").value >= 1500) {\n if (manpower >= 1e3) {\n this._host.game.resPool.get("manpower").value -= 1e3;\n const unlockedRace = mustExist(this._host.game.diplomacy.unlockRandomRace());\n this._host.engine.iactivity("upgrade.race", [unlockedRace.title], "ks-upgrade");\n manpower -= 1e3;\n context.requestGameUiRefresh = true;\n }\n }\n if (!this._host.game.diplomacy.get("zebras").unlocked && this._host.game.resPool.get("ship").value >= 1) {\n if (manpower >= 1e3) {\n this._host.game.resPool.get("manpower").value -= 1e3;\n const unlockedRace = mustExist(this._host.game.diplomacy.unlockRandomRace());\n this._host.engine.iactivity("upgrade.race", [unlockedRace.title], "ks-upgrade");\n manpower -= 1e3;\n context.requestGameUiRefresh = true;\n }\n }\n if (!this._host.game.diplomacy.get("spiders").unlocked && mustExist(this._host.game.resPool.get("ship")).value >= 100 && mustExist(this._host.game.resPool.get("science")).maxValue > 125e3) {\n if (manpower >= 1e3) {\n mustExist(this._host.game.resPool.get("manpower")).value -= 1e3;\n const unlockedRace = mustExist(this._host.game.diplomacy.unlockRandomRace());\n this._host.engine.iactivity("upgrade.race", [unlockedRace.title], "ks-upgrade");\n manpower -= 1e3;\n context.requestGameUiRefresh = true;\n }\n }\n if (!this._host.game.diplomacy.get("dragons").unlocked && this._host.game.science.get("nuclearFission").researched) {\n if (manpower >= 1e3) {\n mustExist(this._host.game.resPool.get("manpower")).value -= 1e3;\n const unlockedRace = mustExist(this._host.game.diplomacy.unlockRandomRace());\n this._host.engine.iactivity("upgrade.race", [unlockedRace.title], "ks-upgrade");\n manpower -= 1e3;\n context.requestGameUiRefresh = true;\n }\n }\n }\n }\n autoTradeBlackcoin() {\n const coinPrice = this._host.game.calendar.cryptoPrice;\n const relicsInitial = this._host.game.resPool.get("relic").value;\n const coinsInitial = this._host.game.resPool.get("blackcoin").value;\n let coinsExchanged = 0;\n let relicsExchanged = 0;\n if (coinPrice < this.settings.tradeBlackcoin.buy && this.settings.tradeBlackcoin.trigger < relicsInitial) {\n this._host.game.diplomacy.buyBcoin();\n const currentCoin = this._host.game.resPool.get("blackcoin").value;\n coinsExchanged = Math.round(currentCoin - coinsInitial);\n this._host.engine.iactivity("act.blackcoin.buy", [this._host.renderAbsolute(coinsExchanged)]);\n } else if (coinPrice > this.settings.tradeBlackcoin.sell && 0 < this._host.game.resPool.get("blackcoin").value) {\n this._host.game.diplomacy.sellBcoin();\n const relicsCurrent = mustExist(this._host.game.resPool.get("relic")).value;\n relicsExchanged = Math.round(relicsCurrent - relicsInitial);\n this._host.engine.iactivity("act.blackcoin.sell", [\n this._host.renderAbsolute(relicsExchanged)\n ]);\n }\n }\n /**\n * Trade with the given race.\n *\n * @param name The race to trade with.\n * @param amount How often to trade with the race.\n */\n trade(name, amount) {\n var _a;\n const race = this.getRace(name);\n const button2 = this.getTradeButton(race.name);\n if (!((_a = button2 == null ? void 0 : button2.model) == null ? void 0 : _a.enabled) || !this.settings.races[name].enabled) {\n console.warn(\n ...cl(\n "KS trade checks are not functioning properly, please create an issue on the github page."\n )\n );\n }\n this._host.game.diplomacy.tradeMultiple(race, amount);\n this._host.engine.storeForSummary(race.title, amount, "trade");\n this._host.engine.iactivity(\n "act.trade",\n [this._host.renderAbsolute(amount), ucfirst(race.title)],\n "ks-trade"\n );\n }\n /**\n * Determine if a trade with the given race would be considered profitable.\n *\n * @param name The race to trade with.\n * @returns `true` if the trade is profitable; `false` otherwise.\n */\n getProfitability(name) {\n const race = this.getRace(name);\n let cost = 0;\n const materials = this.getMaterials(name);\n for (const [mat, amount] of objectEntries(materials)) {\n const tick = this._workshopManager.getTickVal(this._workshopManager.getResource(mat));\n if (tick === "ignore") {\n continue;\n }\n if (tick <= 0) {\n return false;\n }\n cost += amount / tick;\n }\n let profit = 0;\n const output = this.getAverageTrade(race);\n for (const [prod, amount] of objectEntries(output)) {\n const resource = this._workshopManager.getResource(prod);\n const tick = this._workshopManager.getTickVal(resource);\n if (tick === "ignore") {\n continue;\n }\n if (tick <= 0) {\n return true;\n }\n profit += // For capped resources...\n 0 < resource.maxValue ? (\n // ... only add as much to the profit as we can store.\n Math.min(amount, Math.max(resource.maxValue - resource.value, 0)) / tick\n ) : (\n // For uncapped resources, add all of it.\n amount / tick\n );\n }\n return cost <= profit;\n }\n /**\n * Determine which resources and how much of them a trade with the given race results in.\n *\n * @param race The race to check.\n * @returns The resources returned from an average trade and their amount.\n */\n getAverageTrade(race) {\n const standingRatio = this._host.game.getEffect("standingRatio") + this._host.game.diplomacy.calculateStandingFromPolicies(race.name, this._host.game);\n const raceRatio = 1 + race.energy * 0.02;\n const tradeRatio = 1 + this._host.game.diplomacy.getTradeRatio() + this._host.game.diplomacy.calculateTradeBonusFromPolicies(race.name, this._host.game);\n const failedRatio = race.standing < 0 ? race.standing + standingRatio : 0;\n const successRatio = 0 < failedRatio ? 1 + failedRatio : 1;\n const bonusRatio = 0 < race.standing ? Math.min(race.standing + standingRatio / 2, 1) : 0;\n const output = {};\n for (const item of race.sells) {\n if (!this._isValidTrade(item, race)) {\n output[item.name] = 0;\n continue;\n }\n let mean = 0;\n const tradeChance = race.embassyPrices ? item.chance * (1 + this._host.game.getLimitedDR(0.01 * race.embassyLevel, 0.75)) : item.chance;\n if (race.name === "zebras" && item.name === "titanium") {\n const shipCount = this._host.game.resPool.get("ship").value;\n const titaniumProbability = Math.min(0.15 + shipCount * 35e-4, 1);\n const titaniumRatio = 1 + shipCount / 50;\n mean = 1.5 * titaniumRatio * (successRatio * titaniumProbability);\n } else {\n const seasionRatio = !item.seasons ? 1 : 1 + item.seasons[this._host.game.calendar.getCurSeason().name];\n const normBought = (successRatio - bonusRatio) * Math.min(tradeChance / 100, 1);\n const normBonus = bonusRatio * Math.min(tradeChance / 100, 1);\n mean = (normBought + 1.25 * normBonus) * item.value * raceRatio * seasionRatio * tradeRatio;\n }\n output[item.name] = mean;\n }\n const spiceChance = race.embassyPrices ? 0.35 * (1 + 0.01 * race.embassyLevel) : 0.35;\n const spiceTradeAmount = successRatio * Math.min(spiceChance, 1);\n output.spice = 25 * spiceTradeAmount + 50 * spiceTradeAmount * tradeRatio / 2;\n output.blueprint = 0.1 * successRatio;\n return output;\n }\n /**\n * Determine if this trade is valid.\n *\n * @param item The tradeable item.\n * @param race The race to trade with.\n * @returns `true` if the trade is valid; `false` otherwise.\n */\n _isValidTrade(item, race) {\n return (\n // Do we have enough embassies to receive the item?\n !(item.minLevel && race.embassyLevel < item.minLevel) && // TODO: These seem a bit too magical.\n (this._host.game.resPool.get(item.name).unlocked || item.name === "titanium" || item.name === "uranium" || race.name === "leviathans")\n );\n }\n /**\n * Determine how many trades are at least possible.\n *\n * @param name The race to trade with.\n * @param _limited Is the race set to be limited.\n * @param _trigConditions Ignored\n * @returns The lowest number of trades possible with this race.\n */\n getLowestTradeAmount(name, _limited, _trigConditions) {\n let amount;\n const materials = this.getMaterials(name);\n let total;\n for (const [resource, required] of objectEntries(materials)) {\n if (resource === "manpower") {\n let manpowerCost = required;\n if (this._host.game.challenges.isActive("postApocalypse")) {\n manpowerCost = required * (1 + this._host.game.bld.getPollutionLevel());\n }\n total = this._workshopManager.getValueAvailable(resource) / manpowerCost;\n } else if (resource === "gold") {\n let goldCost = required;\n if (this._host.game.challenges.isActive("postApocalypse")) {\n goldCost = required * (1 + this._host.game.bld.getPollutionLevel());\n }\n total = this._workshopManager.getValueAvailable(resource) / goldCost;\n } else {\n total = this._workshopManager.getValueAvailable(resource) / required;\n }\n amount = amount === void 0 || total < amount ? total : amount;\n }\n amount = Math.floor(amount ?? 0);\n if (amount === 0) {\n return 0;\n }\n if (name === null || name === "leviathans") {\n return amount;\n }\n const race = this.getRace(name);\n let highestCapacity = 0;\n const tradeOutput = this.getAverageTrade(race);\n for (const item of race.sells) {\n const resource = this._workshopManager.getResource(item.name);\n let max = 0;\n if (!resource.maxValue) {\n continue;\n }\n max = mustExist(tradeOutput[item.name]);\n const capacity = Math.max((resource.maxValue - resource.value) / max, 0);\n highestCapacity = capacity < highestCapacity ? highestCapacity : capacity;\n }\n highestCapacity = Math.ceil(highestCapacity);\n if (highestCapacity === 0) {\n return 0;\n }\n amount = highestCapacity < amount ? Math.max(highestCapacity - 1, 1) : amount;\n return Math.floor(amount);\n }\n /**\n * Determine the resources required to trade with the given race.\n *\n * @param race The race to check. If not specified the resources for any\n * trade will be returned.\n * @returns The resources need to trade with the race.\n */\n getMaterials(race = null) {\n const materials = {\n gold: 15 - this._host.game.getEffect("tradeGoldDiscount"),\n manpower: 50 - this._host.game.getEffect("tradeCatpowerDiscount")\n };\n if (isNil(race)) {\n return materials;\n }\n const prices = this.getRace(race).buys;\n for (const price of prices) {\n materials[price.name] = price.val;\n }\n return materials;\n }\n /**\n * Retrieve information about the given race from the game.\n *\n * @param name The race to get the information object for.\n * @returns The information object for the given race.\n */\n getRace(name) {\n const raceInfo = this._host.game.diplomacy.get(name);\n if (isNil(raceInfo)) {\n throw new Error(`Unable to retrieve race \'${name}\'`);\n }\n return raceInfo;\n }\n /**\n * Retrieve a reference to the trade button for the given race from the game.\n *\n * @param race The race to get the button reference for.\n * @returns The reference to the trade button.\n */\n getTradeButton(race) {\n const panel = this.manager.tab.racePanels.find((subject) => subject.race.name === race);\n return (panel == null ? void 0 : panel.tradeBtn) ?? null;\n }\n /**\n * Determine if at least a single trade can be made.\n *\n * @param trade - The trade option to check. If not specified, all races are checked.\n * @returns If the requested trade is possible.\n */\n singleTradePossible(sectionTrigger, catpower, gold, trade) {\n const trigger = trade ? Engine.evaluateSubSectionTrigger(sectionTrigger, trade.trigger) : sectionTrigger;\n if (trigger < 0 && trade === void 0) {\n return true;\n }\n if (trigger < 0 && trade !== void 0) {\n return false;\n }\n if (catpower.value / catpower.maxValue < trigger || gold.value / gold.maxValue < trigger) {\n return false;\n }\n const materials = this.getMaterials(trade == null ? void 0 : trade.race);\n for (const [resource, amount] of objectEntries(materials)) {\n if (this._workshopManager.getValueAvailable(resource) < amount) {\n return false;\n }\n }\n return true;\n }\n }\n class MaterialsCache {\n constructor(host) {\n __publicField(this, "_host");\n __publicField(this, "_cache", new Array());\n __publicField(this, "_cacheSum", {});\n this._host = host;\n }\n /**\n * Store a set of materials in the cache.\n * This is usually done *after* hunting and trading.\n * TODO: This is indicative of the desire to know the resource state at the beginning of\n * a frame. This is likely required to make different automations play nice together.\n *\n * @param data The materials to store in the cache.\n * @param data.materials The materials themselves.\n * @param data.timeStamp The current time.\n */\n pushToCache(data) {\n this._cache.push(data);\n for (const [mat, amount] of objectEntries(data.materials)) {\n if (!this._cacheSum[mat]) {\n this._cacheSum[mat] = 0;\n }\n this._cacheSum[mat] += amount;\n }\n for (let cacheIndex = 0; cacheIndex < this._cache.length; ++cacheIndex) {\n const oldData = this._cache[cacheIndex];\n if (this._cache.length > 1e4) {\n const oldMaterials = oldData.materials;\n for (const [mat, amount] of objectEntries(oldMaterials)) {\n if (!this._cacheSum[mat]) {\n this._cacheSum[mat] = 0;\n }\n this._cacheSum[mat] -= amount;\n }\n this._cache.shift();\n cacheIndex--;\n } else {\n return;\n }\n }\n }\n /**\n * Retrieve the resource amount that is stored in the cache.\n *\n * @param resource The resource to check.\n * @returns The cached resource amount, divided by how long it has been cached.\n */\n getResValue(resource) {\n if (this._cache.length === 0 || !this._cacheSum[resource]) {\n return 0;\n }\n const currentTick = this._host.game.timer.ticksTotal;\n const startingTick = this._cache[0].timeStamp;\n return this._cacheSum[resource] / (currentTick - startingTick);\n }\n }\n class VillageManager {\n constructor(host, workshopManager, settings = new VillageSettings()) {\n __publicField(this, "_host");\n __publicField(this, "settings");\n __publicField(this, "manager");\n __publicField(this, "_cacheManager");\n __publicField(this, "_workshopManager");\n this._host = host;\n this.settings = settings;\n this.manager = new TabManager(this._host, "Village");\n this._cacheManager = new MaterialsCache(this._host);\n this._workshopManager = workshopManager;\n }\n tick(_context) {\n if (!this.settings.enabled) {\n return;\n }\n this.autoDistributeKittens();\n if (this.settings.hunt.enabled) {\n this.autoHunt(this._cacheManager);\n }\n if (this.settings.holdFestivals.enabled) {\n this.autoFestival(this._cacheManager);\n }\n if (this.settings.electLeader.enabled) {\n this.autoElect();\n }\n if (this.settings.promoteLeader.enabled) {\n this.autoPromoteLeader();\n }\n if (this.settings.promoteKittens.enabled) {\n this.autoPromoteKittens();\n }\n }\n autoDistributeKittens() {\n const freeKittens = this._host.game.village.getFreeKittens();\n if (!freeKittens) {\n return;\n }\n for (let assignedKitten = 0; assignedKitten < freeKittens; ++assignedKitten) {\n const jobsNotCapped = new Array();\n for (const job of this._host.game.village.jobs) {\n const enabled = this.settings.jobs[job.name].enabled;\n const unlocked = job.unlocked;\n if (!enabled || !unlocked) {\n continue;\n }\n const maxKittensInJob = this._host.game.village.getJobLimit(job.name);\n const maxKittensToAssign = negativeOneToInfinity(this.settings.jobs[job.name].max);\n const kittensInJob = job.value;\n if (kittensInJob < maxKittensInJob && kittensInJob < maxKittensToAssign) {\n jobsNotCapped.push({ count: kittensInJob, job, toCap: maxKittensInJob - kittensInJob });\n }\n }\n if (!jobsNotCapped.length) {\n return;\n }\n const noFarmersAssigned = !isNil(\n jobsNotCapped.find((job) => job.job.name === "farmer" && job.count === 0)\n );\n jobsNotCapped.sort((a, b) => a.count - b.count);\n const jobName = noFarmersAssigned ? "farmer" : jobsNotCapped[0].job.name;\n this._host.game.village.assignJob(this._host.game.village.getJob(jobName), 1);\n this.manager.render();\n this._host.engine.iactivity(\n "act.distribute",\n [this._host.engine.i18n(`$village.job.${jobName}`)],\n "ks-distribute"\n );\n }\n this._host.engine.storeForSummary("distribute", freeKittens);\n }\n autoElect() {\n if (this._host.game.challenges.isActive("anarchy")) {\n return;\n }\n const kittens = this._host.game.village.sim.kittens;\n const leader = this._host.game.village.leader;\n const job = this.settings.electLeader.job.selected;\n const trait = this.settings.electLeader.trait.selected;\n const leaderCandidates = kittens.filter(\n (kitten) => (kitten.job === job || job === "any") && kitten.trait.name === trait\n );\n if (leaderCandidates.length === 0) {\n return;\n }\n leaderCandidates.sort((a, b) => b.rank - a.rank);\n const bestLeader = leaderCandidates[0];\n if (!isNil(leader)) {\n if (leader.trait.name === trait && (leader.job === job || job === "any") && bestLeader.rank <= leader.rank) {\n return;\n }\n }\n this._host.game.village.makeLeader(bestLeader);\n this._host.engine.iactivity("act.elect");\n }\n autoPromoteKittens() {\n const gold = this._workshopManager.getResource("gold");\n if (this.settings.promoteKittens.trigger < gold.value / gold.maxValue) {\n return;\n }\n for (let kittenIndex = 0; kittenIndex < this._host.game.village.sim.kittens.length; kittenIndex++) {\n let tier = -1;\n const engineerSpeciality = this._host.game.village.sim.kittens[kittenIndex].engineerSpeciality;\n if (isNil(engineerSpeciality)) {\n continue;\n }\n tier = mustExist(this._host.game.workshop.getCraft(engineerSpeciality)).tier;\n if (tier <= this._host.game.village.sim.kittens[kittenIndex].rank) {\n continue;\n }\n this._host.game.village.promoteKittens();\n return;\n }\n }\n autoPromoteLeader() {\n var _a, _b;\n if (this._host.game.science.get("civil").researched && this._host.game.village.leader !== null) {\n const leader = this._host.game.village.leader;\n const rank = leader.rank;\n const gold = this._workshopManager.getResource("gold");\n const goldStock = this._workshopManager.getStock("gold");\n if (this._host.game.village.sim.goldToPromote(rank, rank + 1, gold.value - goldStock)[0] && this._host.game.village.sim.promote(leader, rank + 1) === 1) {\n this._host.engine.iactivity("act.promote", [rank + 1], "ks-promote");\n (_a = this._host.game.villageTab.censusPanel) == null ? void 0 : _a.census.renderGovernment(\n this._host.game.villageTab.censusPanel.census.container\n );\n (_b = this._host.game.villageTab.censusPanel) == null ? void 0 : _b.census.update();\n this._host.engine.storeForSummary("promote", 1);\n }\n }\n }\n autoHunt(cacheManager) {\n const manpower = this._workshopManager.getResource("manpower");\n const trigger = this.settings.hunt.trigger;\n if (manpower.value < 100 || this._host.game.challenges.isActive("pacifism")) {\n return;\n }\n if (trigger <= manpower.value / manpower.maxValue && 100 <= manpower.value) {\n const huntCount = Math.floor(manpower.value / 100);\n this._host.engine.storeForSummary("hunt", huntCount);\n this._host.engine.iactivity("act.hunt", [this._host.renderAbsolute(huntCount)], "ks-hunt");\n const averageOutput = this._workshopManager.getAverageHunt();\n const trueOutput = {};\n for (const [out, outValue] of objectEntries(averageOutput)) {\n const res = this._workshopManager.getResource(out);\n trueOutput[out] = // If this is a capped resource...\n 0 < res.maxValue ? (\n // multiply the amount of times we hunted with the result of an average hunt.\n // Capping at the max value and 0 bounds.\n Math.min(outValue * huntCount, Math.max(res.maxValue - res.value, 0))\n ) : (\n // Otherwise, just multiply unbounded\n outValue * huntCount\n );\n }\n if (!isNil(cacheManager)) {\n cacheManager.pushToCache({\n materials: trueOutput,\n timeStamp: this._host.game.timer.ticksTotal\n });\n }\n this._host.game.village.huntAll();\n }\n }\n autoFestival(cacheManager) {\n if (!this._host.game.science.get("drama").researched || 400 < this._host.game.calendar.festivalDays) {\n return;\n }\n if (!this._host.game.prestige.getPerk("carnivals").researched && 0 < this._host.game.calendar.festivalDays) {\n return;\n }\n const craftManager = this._workshopManager;\n if (craftManager.getValueAvailable("manpower") < 1500 || craftManager.getValueAvailable("culture") < 5e3 || craftManager.getValueAvailable("parchment") < 2500) {\n return;\n }\n const catpowProfitable = 4e3 * craftManager.getTickVal(\n craftManager.getResource("manpower"),\n cacheManager,\n true\n ) > 1500;\n const cultureProfitable = 4e3 * craftManager.getTickVal(\n craftManager.getResource("culture"),\n cacheManager,\n true\n ) > 5e3;\n const parchProfitable = 4e3 * craftManager.getTickVal(\n craftManager.getResource("parchment"),\n cacheManager,\n true\n ) > 2500;\n if (!catpowProfitable && !cultureProfitable && !parchProfitable) {\n return;\n }\n this.manager.render();\n if (this._host.game.villageTab.festivalBtn.model.enabled) {\n const beforeDays = this._host.game.calendar.festivalDays;\n this._host.game.villageTab.festivalBtn.onClick();\n this._host.engine.storeForSummary("festival");\n if (beforeDays > 0) {\n this._host.engine.iactivity("festival.extend", [], "ks-festival");\n } else {\n this._host.engine.iactivity("festival.hold", [], "ks-festival");\n }\n }\n }\n }\n const i18nData = { "de-DE": deDE, "en-US": enUS$1, "he-IL": heIL, "zh-CN": zhCN$1 };\n class Engine {\n constructor(host, gameLanguage) {\n /**\n * All i18n literals of the userscript.\n */\n __publicField(this, "_i18nData");\n /**\n * Was any state loaded into this engine at any point in time?\n */\n __publicField(this, "_isLoaded", false);\n __publicField(this, "_host");\n __publicField(this, "settings");\n __publicField(this, "bonfireManager");\n __publicField(this, "religionManager");\n __publicField(this, "scienceManager");\n __publicField(this, "spaceManager");\n __publicField(this, "timeControlManager");\n __publicField(this, "timeManager");\n __publicField(this, "tradeManager");\n __publicField(this, "villageManager");\n __publicField(this, "workshopManager");\n __publicField(this, "_activitySummary");\n __publicField(this, "_timeoutMainLoop");\n this.settings = new EngineSettings();\n this._i18nData = i18nData;\n this.setLanguage(gameLanguage, false);\n this._host = host;\n this._activitySummary = new ActivitySummary(this._host);\n this.workshopManager = new WorkshopManager(this._host);\n this.bonfireManager = new BonfireManager(this._host, this.workshopManager);\n this.religionManager = new ReligionManager(\n this._host,\n this.bonfireManager,\n this.workshopManager\n );\n this.scienceManager = new ScienceManager(this._host, this.workshopManager);\n this.spaceManager = new SpaceManager(this._host, this.workshopManager);\n this.timeControlManager = new TimeControlManager(\n this._host,\n this.bonfireManager,\n this.religionManager,\n this.spaceManager,\n this.workshopManager\n );\n this.timeManager = new TimeManager(this._host, this.workshopManager);\n this.tradeManager = new TradeManager(this._host, this.workshopManager);\n this.villageManager = new VillageManager(this._host, this.workshopManager);\n }\n get isLoaded() {\n return this._isLoaded;\n }\n isLanguageSupported(language) {\n return Object.keys(this._i18nData).some((locale) => locale.startsWith(`${language}-`));\n }\n isLocaleSupported(locale) {\n return locale in this._i18nData;\n }\n localeSupportsFirstLetterSplits(locale = this.settings.locale.selected) {\n return locale !== "zh-CN";\n }\n localeForLanguage(language) {\n return Object.keys(this._i18nData).find(\n (locale) => locale.startsWith(`${language}-`)\n );\n }\n setLanguage(language, rebuildUI = true) {\n const previousLocale = this.settings.locale.selected;\n if (!this.isLanguageSupported(language)) {\n console.warn(\n ...cl(\n `Requested language \'${language}\' is not available. Falling back to \'${FallbackLocale}\'.`\n )\n );\n this.settings.locale.selected = FallbackLocale;\n } else {\n const locale = mustExist(this.localeForLanguage(language));\n console.info(...cl(`Selecting language \'${locale}\'.`));\n this.settings.locale.selected = locale;\n }\n if (previousLocale !== this.settings.locale.selected && rebuildUI) {\n this._host.rebuildUi();\n }\n }\n setLocale(locale, rebuildUI = true) {\n const previousLocale = this.settings.locale.selected;\n if (!this.isLocaleSupported(locale)) {\n console.warn(\n ...cl(\n `Requested language \'${locale}\' is not available. Falling back to \'${FallbackLocale}\'.`\n )\n );\n this.settings.locale.selected = FallbackLocale;\n } else {\n console.info(...cl(`Selecting language \'${locale}\'.`));\n this.settings.locale.selected = locale;\n }\n if (previousLocale !== this.settings.locale.selected && rebuildUI) {\n this._host.rebuildUi();\n }\n }\n /**\n * Loads a new state into the engine.\n *\n * @param settings The engine state to load.\n * @param retainMetaBehavior When set to `true`, the engine will not be stopped or started, if the engine\n * state would require that. The settings for state management are also not loaded from the engine state.\n * This is intended to make loading of previous settings snapshots more intuitive.\n */\n stateLoad(settings, retainMetaBehavior = false) {\n this._isLoaded = true;\n this.stop(false);\n const version = ksVersion();\n if (settings.v !== version) {\n console.warn(\n ...cl(\n `Attempting to load engine state with version tag \'${settings.v}\' when engine is at version \'${version}\'!`\n )\n );\n }\n const attemptLoad = (loader, errorMessage) => {\n try {\n loader();\n } catch (error) {\n console.error(...cl(`Failed load of ${errorMessage} settings.`, error));\n }\n };\n attemptLoad(() => {\n this.settings.load(settings.engine, retainMetaBehavior);\n }, "engine");\n attemptLoad(() => {\n this.bonfireManager.settings.load(settings.bonfire);\n }, "bonfire");\n attemptLoad(() => {\n this.religionManager.settings.load(settings.religion);\n }, "religion");\n attemptLoad(() => {\n this.scienceManager.settings.load(settings.science);\n }, "science");\n attemptLoad(() => {\n this.spaceManager.settings.load(settings.space);\n }, "space");\n attemptLoad(() => {\n this.timeControlManager.settings.load(settings.timeControl);\n }, "time control");\n attemptLoad(() => {\n this.timeManager.settings.load(settings.time);\n }, "time");\n attemptLoad(() => {\n this.tradeManager.settings.load(settings.trade);\n }, "trade");\n attemptLoad(() => {\n this.villageManager.settings.load(settings.village);\n }, "village");\n attemptLoad(() => {\n this.workshopManager.settings.load(settings.workshop);\n }, "workshop");\n this.setLocale(this.settings.locale.selected);\n if (this.settings.enabled) {\n this.start(false);\n } else {\n this.stop(false);\n }\n }\n static get DEFAULT_STATE() {\n return {\n bonfire: new BonfireSettings(),\n engine: new EngineSettings(),\n religion: new ReligionSettings(),\n science: new ScienceSettings(),\n space: new SpaceSettings(),\n time: new TimeSettings(),\n timeControl: new TimeControlSettings(),\n trade: new TradeSettings(),\n v: ksVersion(),\n village: new VillageSettings(),\n workshop: new WorkshopSettings()\n };\n }\n stateReset() {\n this.stateLoad(Engine.DEFAULT_STATE);\n }\n /**\n * Serializes all settings in the engine.\n *\n * @returns A snapshot of the current engine settings state.\n */\n stateSerialize() {\n return {\n bonfire: this.bonfireManager.settings,\n engine: this.settings,\n religion: this.religionManager.settings,\n science: this.scienceManager.settings,\n space: this.spaceManager.settings,\n time: this.timeManager.settings,\n timeControl: this.timeControlManager.settings,\n trade: this.tradeManager.settings,\n v: ksVersion(),\n village: this.villageManager.settings,\n workshop: this.workshopManager.settings\n };\n }\n /**\n * Start the Kitten Scientists engine.\n *\n * @param msg Should we print to the log that the engine was started?\n */\n start(msg = true) {\n if (this._timeoutMainLoop) {\n return;\n }\n const loop = () => {\n const context = {\n entry: Date.now(),\n exit: 0,\n measurements: {},\n requestGameUiRefresh: false\n };\n this._iterate(context).then(() => {\n context.exit = Date.now();\n const timeTaken = context.exit - context.entry;\n document.dispatchEvent(\n new CustomEvent("ks.reportFrame", { detail: context })\n );\n if (this._timeoutMainLoop === void 0) {\n return;\n }\n this._timeoutMainLoop = UserScriptLoader.window.setTimeout(\n loop,\n Math.max(10, this._host.engine.settings.interval - timeTaken)\n );\n }).catch((error) => {\n console.warn(...cl(unknownToError(error)));\n });\n };\n this._timeoutMainLoop = UserScriptLoader.window.setTimeout(\n loop,\n this._host.engine.settings.interval\n );\n if (msg) {\n this._host.engine.imessage("status.ks.enable");\n }\n }\n /**\n * Stop the Kitten Scientists engine.\n *\n * @param msg Should we print to the log that the engine was stopped?\n */\n stop(msg = true) {\n if (!this._timeoutMainLoop) {\n return;\n }\n clearTimeout(this._timeoutMainLoop);\n this._timeoutMainLoop = void 0;\n if (msg) {\n this._host.engine.imessage("status.ks.disable");\n }\n }\n /**\n * The main loop of the automation script.\n */\n async _iterate(context) {\n if (!this.settings.filters.disableKGLog.enabled) {\n this._maintainKGLogFilters();\n }\n let [, duration] = await measureAsync(() => this.scienceManager.tick(context));\n context.measurements.scienceManager = duration;\n [, duration] = measure(() => {\n this.bonfireManager.tick(context);\n });\n context.measurements.bonfireManager = duration;\n [, duration] = measure(() => {\n this.spaceManager.tick(context);\n });\n context.measurements.spaceManager = duration;\n [, duration] = await measureAsync(() => this.workshopManager.tick(context));\n context.measurements.workshopManager = duration;\n [, duration] = measure(() => {\n this.tradeManager.tick(context);\n });\n context.measurements.tradeManager = duration;\n [, duration] = await measureAsync(() => this.religionManager.tick(context));\n context.measurements.religionManager = duration;\n [, duration] = measure(() => {\n this.timeManager.tick(context);\n });\n context.measurements.timeManager = duration;\n [, duration] = measure(() => {\n this.villageManager.tick(context);\n });\n context.measurements.villageManager = duration;\n [, duration] = await measureAsync(() => this.timeControlManager.tick(context));\n context.measurements.timeControlManager = duration;\n [, duration] = measure(() => {\n if (context.requestGameUiRefresh) {\n this._host.game.ui.render();\n }\n });\n context.measurements.gameUiRefresh = duration;\n }\n /**\n * Ensures all log filters in KG are unchecked. This means the events will not be logged.\n */\n _maintainKGLogFilters() {\n for (const filter of Object.values(this._host.game.console.filters)) {\n filter.enabled = false;\n }\n const filterCheckboxes = UserScriptLoader.window.document.querySelectorAll("[id^=filter-]");\n for (const checkbox2 of filterCheckboxes) {\n checkbox2.checked = false;\n }\n }\n symbolForCycle(cycle) {\n var _a;\n return ((_a = this._host.game.calendar.cycles.find((entry) => entry.name === cycle)) == null ? void 0 : _a.uglyph) ?? "";\n }\n labelForCycle(cycle) {\n const symbol = this.symbolForCycle(cycle);\n const label2 = this._host.engine.i18n(\n `$space.planet.${cycle === "redmoon" ? "moon" : cycle}.label`\n );\n return `${symbol} ${label2}`;\n }\n labelForPlanet(planet) {\n const cycleCandidate = planet === "moon" ? "redmoon" : planet;\n const cycle = Cycles.includes(cycleCandidate) ? cycleCandidate : void 0;\n const label2 = this._host.engine.i18n(`$space.planet.${planet}.label`);\n return cycle === void 0 ? label2 : `${this.symbolForCycle(cycle)} ${label2}`;\n }\n /**\n * Retrieve an internationalized string literal.\n *\n * @param key The key to retrieve from the translation table.\n * @param args Variable arguments to render into the string.\n * @returns The translated string.\n */\n i18n(key, args = []) {\n let value;\n if (key.startsWith("$")) {\n value = this._host.i18nEngine(key.slice(1));\n }\n value = value ?? this._i18nData[this.settings.locale.selected][key];\n const check = value;\n if (isNil(check)) {\n value = i18nData[FallbackLocale][key];\n if (!value) {\n console.warn(...cl(`i18n key \'${key}\' not found in default language.`));\n return `$${key}`;\n }\n console.warn(...cl(`i18n key \'${key}\' not found in selected language.`));\n }\n for (let argIndex = 0; argIndex < args.length; ++argIndex) {\n value = value.replace(`{${argIndex}}`, `${args[argIndex]}`);\n }\n return value;\n }\n iactivity(i18nLiteral, i18nArgs = [], logStyle) {\n const text = this.i18n(i18nLiteral, i18nArgs);\n if (logStyle) {\n const activityClass = `type_${logStyle}`;\n this._printOutput(`ks-activity ${activityClass}`, "#e65C00", text);\n } else {\n this._printOutput("ks-activity", "#e65C00", text);\n }\n }\n imessage(i18nLiteral, i18nArgs = []) {\n this._printOutput("ks-default", "#aa50fe", this.i18n(i18nLiteral, i18nArgs));\n }\n storeForSummary(name, amount = 1, section = "other") {\n this._activitySummary.storeActivity(name, amount, section);\n }\n getSummary() {\n return this._activitySummary.renderSummary();\n }\n displayActivitySummary() {\n const summary = this.getSummary();\n for (const summaryLine of summary) {\n this._printOutput("ks-summary", "#009933", summaryLine);\n }\n this.resetActivitySummary();\n }\n resetActivitySummary() {\n this._activitySummary.resetActivity();\n }\n _printOutput(cssClasses, color, message) {\n if (this.settings.filters.enabled) {\n for (const filterItem of Object.values(this.settings.filters.filters)) {\n if (filterItem.variant === cssClasses && !filterItem.enabled) {\n return;\n }\n }\n }\n const msg = this._host.game.msg(message, cssClasses);\n $(msg.span).css("color", color);\n console.debug(...cl(message));\n }\n static evaluateSubSectionTrigger(sectionTrigger, subSectionTrigger) {\n return sectionTrigger < 0 ? subSectionTrigger : subSectionTrigger < 0 ? sectionTrigger : subSectionTrigger;\n }\n }\n const toZeroIfInfinity = (value) => Number.isFinite(value) ? value : 0;\n const parseNumber = (milliseconds) => {\n return {\n days: Math.trunc(milliseconds / 864e5),\n hours: Math.trunc(milliseconds / 36e5 % 24),\n minutes: Math.trunc(milliseconds / 6e4 % 60),\n seconds: Math.trunc(milliseconds / 1e3 % 60),\n milliseconds: Math.trunc(milliseconds % 1e3),\n microseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e3) % 1e3),\n nanoseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e6) % 1e3)\n };\n };\n const parseBigint = (milliseconds) => {\n return {\n days: milliseconds / 86400000n,\n hours: milliseconds / 3600000n % 24n,\n minutes: milliseconds / 60000n % 60n,\n seconds: milliseconds / 1000n % 60n,\n milliseconds: milliseconds % 1000n,\n microseconds: 0n,\n nanoseconds: 0n\n };\n };\n const parseMilliseconds = (milliseconds) => {\n switch (typeof milliseconds) {\n case "number": {\n if (Number.isFinite(milliseconds)) {\n return parseNumber(milliseconds);\n }\n break;\n }\n case "bigint": {\n return parseBigint(milliseconds);\n }\n }\n throw new TypeError("Expected a finite number or bigint");\n };\n const isZero = (value) => value === 0 || value === 0n;\n const pluralize = (word, count) => count === 1 || count === 1n ? word : `${word}s`;\n const SECOND_ROUNDING_EPSILON = 1e-7;\n const ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n;\n const formatMilliseconds = (milliseconds, options = {\n colonNotation: false,\n compact: false,\n formatSubMilliseconds: false,\n keepDecimalsOnWholeSeconds: false,\n millisecondsDecimalDigits: 0,\n secondsDecimalDigits: 1,\n separateMilliseconds: false,\n unitCount: Infinity,\n verbose: false\n }) => {\n const isBigInt = typeof milliseconds === "bigint";\n if (!isBigInt && !Number.isFinite(milliseconds)) {\n throw new TypeError("Expected a finite number or bigint");\n }\n const optionsAdjusted = { ...options };\n if (optionsAdjusted.colonNotation) {\n optionsAdjusted.compact = false;\n optionsAdjusted.formatSubMilliseconds = false;\n optionsAdjusted.separateMilliseconds = false;\n optionsAdjusted.verbose = false;\n }\n if (optionsAdjusted.compact) {\n optionsAdjusted.unitCount = 1;\n optionsAdjusted.secondsDecimalDigits = 0;\n optionsAdjusted.millisecondsDecimalDigits = 0;\n }\n let result = [];\n const floorDecimals = (value, decimalDigits) => {\n const flooredInterimValue = Math.floor(value * 10 ** decimalDigits + SECOND_ROUNDING_EPSILON);\n const flooredValue = Math.round(flooredInterimValue) / 10 ** decimalDigits;\n return flooredValue.toFixed(decimalDigits);\n };\n const add = (value, long, short, valueString) => {\n if ((result.length === 0 || !optionsAdjusted.colonNotation) && isZero(value) && !(optionsAdjusted.colonNotation && short === "m")) {\n return;\n }\n valueString ?? (valueString = String(value));\n if (optionsAdjusted.colonNotation) {\n const wholeDigits = valueString.includes(".") ? valueString.split(".")[0].length : valueString.length;\n const minLength = result.length > 0 ? 2 : 1;\n valueString = "0".repeat(Math.max(0, minLength - wholeDigits)) + valueString;\n } else {\n valueString += optionsAdjusted.verbose ? " " + pluralize(long, value) : short;\n }\n result.push(valueString);\n };\n const parsed = parseMilliseconds(milliseconds);\n const days = BigInt(parsed.days);\n add(days / 365n, "year", "y");\n add(days % 365n, "day", "d");\n add(Number(parsed.hours), "hour", "h");\n add(Number(parsed.minutes), "minute", "m");\n if (optionsAdjusted.separateMilliseconds || optionsAdjusted.formatSubMilliseconds || !optionsAdjusted.colonNotation && milliseconds < 1e3) {\n const seconds = Number(parsed.seconds);\n const milliseconds2 = Number(parsed.milliseconds);\n const microseconds = Number(parsed.microseconds);\n const nanoseconds = Number(parsed.nanoseconds);\n add(seconds, "second", "s");\n if (optionsAdjusted.formatSubMilliseconds) {\n add(milliseconds2, "millisecond", "ms");\n add(microseconds, "microsecond", "µs");\n add(nanoseconds, "nanosecond", "ns");\n } else {\n const millisecondsAndBelow = milliseconds2 + microseconds / 1e3 + nanoseconds / 1e6;\n const millisecondsDecimalDigits = typeof optionsAdjusted.millisecondsDecimalDigits === "number" ? optionsAdjusted.millisecondsDecimalDigits : 0;\n const roundedMilliseconds = millisecondsAndBelow >= 1 ? Math.round(millisecondsAndBelow) : Math.ceil(millisecondsAndBelow);\n const millisecondsString = millisecondsDecimalDigits ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) : roundedMilliseconds.toString();\n add(Number.parseFloat(millisecondsString), "millisecond", "ms", millisecondsString);\n }\n } else {\n const seconds = (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) / 1e3 % 60;\n const secondsDecimalDigits = typeof optionsAdjusted.secondsDecimalDigits === "number" ? optionsAdjusted.secondsDecimalDigits : 1;\n const secondsFixed = floorDecimals(seconds, secondsDecimalDigits);\n const secondsString = optionsAdjusted.keepDecimalsOnWholeSeconds ? secondsFixed : secondsFixed.replace(/\\.0+$/, "");\n add(Number.parseFloat(secondsString), "second", "s", secondsString);\n }\n if (result.length === 0) {\n return "0" + (optionsAdjusted.verbose ? " milliseconds" : "ms");\n }\n const separator = optionsAdjusted.colonNotation ? ":" : " ";\n if (typeof optionsAdjusted.unitCount === "number") {\n result = result.slice(0, Math.max(optionsAdjusted.unitCount, 1));\n }\n return result.join(separator);\n };\n const Icons = {\n /**\n * camping_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Bonfire: "M80-80v-183l363-491-67-90 49-35 55 75 56-75 48 35-66 90 362 491v183H80Zm400-623L140-243v103h145l195-273 195 273h145v-103L480-703ZM359-140h242L480-310 359-140Zm121-273 195 273-195-273-195 273 195-273Z",\n /**\n * check_box_48dp__FILL0_wght400_GRAD0_opsz48\n */\n CheckboxCheck: "m419-321 289-289-43-43-246 246-119-119-43 43 162 162ZM120-120v-720h720v720H120Zm60-60h600v-600H180v600Zm0 0v-600 600Z",\n /**\n * check_box_outline_blank_48dp__FILL0_wght400_GRAD0_opsz48\n */\n CheckboxUnCheck: "M120-120v-720h720v720H120Zm60-60h600v-600H180v600Z",\n /**\n * content_copy_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Copy: "M240-200v-680h560v680H240Zm60-60h440v-560H300v560ZM120-80v-680h60v620h500v60H120Zm180-180v-560 560Z",\n /**\n * event_repeat_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Cycles: "M120-80v-740h125v-60h65v60h340v-60h65v60h125v360h-60v-110H180v430h324v60H120ZM760 0q-73 0-127.5-45.5T564-160h62q13 44 49.5 72T760-60q58 0 99-41t41-99q0-58-41-99t-99-41q-29 0-54 10.5T662-300h58v60H560v-160h60v57q27-26 63-41.5t77-15.5q83 0 141.5 58.5T960-200q0 83-58.5 141.5T760 0ZM180-630h600v-130H180v130Zm0 0v-130 130Z",\n /**\n * data_usage_48dp__FILL0_wght400_GRAD0_opsz48\n */\n DataUsage: "M480-80q-82 0-155-31.5T197.5-197q-54.5-54-86-127T80-479q0-158 106.5-272T451-877v102q-115 11-192 95.5T182-479q0 124 87 210.5T480-182q72 0 136-32.5T725-306l88 51q-58 83-145.5 129T480-80Zm362-229-88-49q12-31 18-61.5t6-60.5q0-116-76.5-201T511-776v-102q157 11 263 124.5T880-484q0 45-9.5 88.5T842-309Z",\n /**\n * delete_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Delete: "M201-120v-630h-41v-60h188v-30h264v30h188v60h-41v630H201Zm60-60h438v-570H261v570Zm106-86h60v-399h-60v399Zm166 0h60v-399h-60v399ZM261-750v570-570Z",\n /**\n * draft_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Draft: "M160-80v-800h421l219 219v581H160Zm391-554v-186H220v680h520v-494H551ZM220-820v186-186 680-680Z",\n /**\n * eco_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Eco: "M213-175q-43.59-45-68.3-104Q120-338 120-400q0-73 25.5-133.5T222-645q35-35 87-59t122.5-37.5Q502-755 591-758.5t198 3.5q8 108 5.5 197.5t-16 160.75q-13.5 71.25-38 124.56Q716-218.87 680-183q-51 51-110 77T444-80q-69 0-126.5-23.5T213-175Zm103 0q25 17 58 26t69.92 9Q497-140 547-162t91-64q27-27 46-70.5t31-103Q727-459 731-534t0-165q-94-2-168.5 2.5T431-680q-57 12-98 30.5T266-604q-42 43-64 91t-22 98q0 48 20.5 100.5T251-230q53-98 127-176t157-123q-87 75-141 162.5T316-175Zm0 0Zm0 0Z",\n /**\n * edit_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Edit: "M180-180h44l472-471-44-44-472 471v44Zm-60 60v-128l617-616 128 128-617 616H120Zm659-617-41-41 41 41Zm-105 64-22-22 44 44-22-22Z",\n /**\n * expand_circle_down_48dp__FILL0_wght400_GRAD0_opsz48\n */\n ExpandCircleDown: "m480-351 173-173-43-42-130 130-130-130-43 42 173 173Zm0 271q-82 0-155-31.5t-127.5-86Q143-252 111.5-325T80-480q0-83 31.5-156t86-127Q252-817 325-848.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 82-31.5 155T763-197.5q-54 54.5-127 86T480-80Zm0-60q142 0 241-99.5T820-480q0-142-99-241t-241-99q-141 0-240.5 99T140-480q0 141 99.5 240.5T480-140Zm0-340Z",\n /**\n * expand_circle_up_48dp__FILL0_wght400_GRAD0_opsz48\n */\n ExpandCircleUp: "m350-394 130-130 130 130 43-42-173-173-173 173 43 42ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-155.5t85.5-127q54-54.5 127-86T480-880q83 0 155.5 31.5t127 86q54.5 54.5 86 127T880-480q0 83-31.5 156t-86 127q-54.5 54-127 85.5T480-80Zm0-60q141 0 240.5-99T820-480q0-141-99.5-240.5T480-820q-142 0-241 99.5T140-480q0 142 99 241t241 99Zm0-340Z",\n /**\n * publish_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Import: "M450-160v-371L330-411l-43-43 193-193 193 193-43 43-120-120v371h-60ZM160-597v-203h640v203h-60v-143H220v143h-60Z",\n /**\n * synagogue_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Religion: "M40-120v-560q0-45.83 32.12-77.92 32.12-32.08 78-32.08T228-757.92q32 32.09 32 77.92v31l220-191 220 191v-31q0-45.83 32.12-77.92 32.12-32.08 78-32.08T888-757.92q32 32.09 32 77.92v560H530v-250H430v250H40Zm720-510h100v-49.82q0-21.18-14.32-35.68-14.33-14.5-35.5-14.5-21.18 0-35.68 14.37Q760-701.25 760-680v50Zm-660 0h100v-49.82q0-21.18-14.32-35.68-14.33-14.5-35.5-14.5-21.18 0-35.68 14.37Q100-701.25 100-680v50Zm0 450h100v-390H100v390Zm160 0h110v-250h220v250h110v-390L480-761 260-570v390Zm500 0h100v-390H760v390ZM479.94-505Q457-505 441-521.06q-16-16.06-16-39T441.06-599q16.06-16 39-16T519-598.94q16 16.06 16 39T518.94-521q-16.06 16-39 16Z",\n /**\n * refresh_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Reset: "M480-160q-133 0-226.5-93.5T160-480q0-133 93.5-226.5T480-800q85 0 149 34.5T740-671v-129h60v254H546v-60h168q-38-60-97-97t-137-37q-109 0-184.5 75.5T220-480q0 109 75.5 184.5T480-220q83 0 152-47.5T728-393h62q-29 105-115 169t-195 64Z",\n /**\n * shelves_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Resources: "M120-40v-880h60v80h600v-80h60v880h-60v-80H180v80h-60Zm60-469h110v-160h220v160h270v-271H180v271Zm0 329h270v-160h220v160h110v-269H180v269Zm170-329h100v-100H350v100Zm160 329h100v-100H510v100ZM350-509h100-100Zm160 329h100-100Z",\n /**\n * save_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Save: "M840-683v563H120v-720h563l157 157Zm-60 27L656-780H180v600h600v-476ZM479.76-245q43.24 0 73.74-30.26 30.5-30.27 30.5-73.5 0-43.24-30.26-73.74-30.27-30.5-73.5-30.5-43.24 0-73.74 30.26-30.5 30.27-30.5 73.5 0 43.24 30.26 73.74 30.27 30.5 73.5 30.5ZM233-584h358v-143H233v143Zm-53-72v476-600 124Z",\n /**\n * save_as_48dp__FILL0_wght400_GRAD0_opsz48\n */\n SaveAs: "M120-120v-720h563l157 157v117l-60 60v-150L656-780H180v600h280v60H120Zm60-660v600-600ZM520-40v-123l263-262 122 122L643-40H520Zm300-263-37-37 37 37ZM580-100h38l121-122-18-19-19-18-122 121v38Zm141-141-19-18 37 37-18-19ZM233-584h358v-143H233v143Zm247 339q14 0 27-3t24-10l39-40q7-11 10.5-24t3.5-27q0-43.33-30.26-73.67Q523.47-453 480.24-453q-43.24 0-73.74 30.26-30.5 30.27-30.5 73.5 0 43.24 30.33 73.74Q436.67-245 480-245Z",\n /**\n * date_range_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Seasons: "M306-394q-17 0-28.5-11.5T266-434q0-17 11.5-28.5T306-474q17 0 28.5 11.5T346-434q0 17-11.5 28.5T306-394Zm177 0q-17 0-28.5-11.5T443-434q0-17 11.5-28.5T483-474q17 0 28.5 11.5T523-434q0 17-11.5 28.5T483-394Zm170 0q-17 0-28.5-11.5T613-434q0-17 11.5-28.5T653-474q17 0 28.5 11.5T693-434q0 17-11.5 28.5T653-394ZM120-80v-740h125v-60h65v60h340v-60h65v60h125v740H120Zm60-60h600v-430H180v430Zm0-490h600v-130H180v130Zm0 0v-130 130Z",\n /**\n * settings_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Settings: "m388-80-20-126q-19-7-40-19t-37-25l-118 54-93-164 108-79q-2-9-2.5-20.5T185-480q0-9 .5-20.5T188-521L80-600l93-164 118 54q16-13 37-25t40-18l20-127h184l20 126q19 7 40.5 18.5T669-710l118-54 93 164-108 77q2 10 2.5 21.5t.5 21.5q0 10-.5 21t-2.5 21l108 78-93 164-118-54q-16 13-36.5 25.5T592-206L572-80H388Zm48-60h88l14-112q33-8 62.5-25t53.5-41l106 46 40-72-94-69q4-17 6.5-33.5T715-480q0-17-2-33.5t-7-33.5l94-69-40-72-106 46q-23-26-52-43.5T538-708l-14-112h-88l-14 112q-34 7-63.5 24T306-642l-106-46-40 72 94 69q-4 17-6.5 33.5T245-480q0 17 2.5 33.5T254-413l-94 69 40 72 106-46q24 24 53.5 41t62.5 25l14 112Zm44-210q54 0 92-38t38-92q0-54-38-92t-92-38q-54 0-92 38t-38 92q0 54 38 92t92 38Zm0-130Z",\n /**\n * rocket_launch_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Space: "m187-551 106 45q18-36 38.5-71t43.5-67l-79-16-109 109Zm154 81 133 133q57-26 107-59t81-64q81-81 119-166t41-192q-107 3-192 41T464-658q-31 31-64 81t-59 107Zm229-96q-20-20-20-49.5t20-49.5q20-20 49.5-20t49.5 20q20 20 20 49.5T669-566q-20 20-49.5 20T570-566Zm-15 383 109-109-16-79q-32 23-67 43.5T510-289l45 106Zm326-694q9 136-34 248T705-418l-2 2-2 2 22 110q3 15-1.5 29T706-250L535-78l-85-198-170-170-198-85 172-171q11-11 25-15.5t29-1.5l110 22q1-1 2-1.5t2-1.5q99-99 211-142.5T881-877ZM149-325q35-35 85.5-35.5T320-326q35 35 34.5 85.5T319-155q-26 26-80.5 43T75-80q15-109 31.5-164t42.5-81Zm42 43q-14 15-25 47t-19 82q50-8 82-19t47-25q19-17 19.5-42.5T278-284q-19-18-44.5-17.5T191-282Z",\n /**\n * keyboard_tab_48dp__FILL0_wght400_GRAD0_opsz48\n */\n State: "M820-240v-480h60v480h-60Zm-340 1-43-42 169-169H80v-60h526L438-679l42-42 241 241-241 241Z",\n /**\n * summarize_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Summary: "M279-621h60v-60h-60v60Zm0 171h60v-60h-60v60Zm0 171h60v-60h-60v60ZM120-120v-720h522l198 198v522H120Zm60-60h600v-429H609v-171H180v600Zm0-600v171.43V-780v600-600Z",\n /**\n * sync_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Sync: "M167-160v-60h130l-15-12q-64-51-93-111t-29-134q0-106 62.5-190.5T387-784v62q-75 29-121 96.5T220-477q0 63 23.5 109.5T307-287l30 21v-124h60v230H167Zm407-15v-63q76-29 121-96.5T740-483q0-48-23.5-97.5T655-668l-29-26v124h-60v-230h230v60H665l15 14q60 56 90 120t30 123q0 106-62 191T574-175Z",\n /**\n * schedule_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Time: "m627-287 45-45-159-160v-201h-60v225l174 181ZM480-80q-82 0-155-31.5t-127.5-86Q143-252 111.5-325T80-480q0-82 31.5-155t86-127.5Q252-817 325-848.5T480-880q82 0 155 31.5t127.5 86Q817-708 848.5-635T880-480q0 82-31.5 155t-86 127.5Q708-143 635-111.5T480-80Zm0-400Zm0 340q140 0 240-100t100-240q0-140-100-240T480-820q-140 0-240 100T140-480q0 140 100 240t240 100Z",\n /**\n * bolt_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Trigger: "m393-165 279-335H492l36-286-253 366h154l-36 255Zm-73 85 40-280H160l360-520h80l-40 320h240L400-80h-80Zm154-396Z",\n /**\n * construction_48dp__FILL0_wght400_GRAD0_opsz48\n */\n Workshop: "M768-120 517-371l57-57 251 251-57 57Zm-581 0-57-57 290-290-107-107-23 23-44-44v85l-24 24-122-122 24-24h86l-48-48 131-131q17-17 37-23t44-6q24 0 44 8.5t37 25.5L348-699l48 48-24 24 104 104 122-122q-8-13-12.5-30t-4.5-36q0-53 38.5-91.5T711-841q15 0 25.5 3t17.5 8l-85 85 75 75 85-85q5 8 8.5 19.5T841-709q0 53-38.5 91.5T711-579q-18 0-31-2.5t-24-7.5L187-120Z"\n };\n const _UiComponent = class _UiComponent {\n /**\n * Constructs the base `UiComponent`.\n * Subclasses MUST add children from options when `this.element` is constructed.\n *\n * @param host A reference to the host.\n * @param options The options for this component.\n */\n constructor(parent, options) {\n __publicField(this, "componentId");\n /**\n * A reference to the host itself.\n */\n __publicField(this, "host");\n __publicField(this, "parent");\n __publicField(this, "options");\n /**\n * The main DOM element for this component, in a JQuery wrapper.\n */\n __publicField(this, "_element");\n /**\n * NOTE: It is intentional that all children are of the most fundamental base type.\n * If a more specifically typed reference for a child is required, it should be stored\n * on construction.\n * The \'children\' set is intended only for inter-component orchestration.\n */\n __publicField(this, "children", /* @__PURE__ */ new Set());\n __publicField(this, "_needsRefresh");\n this.componentId = _UiComponent.nextComponentId++;\n this.host = parent.host;\n this.options = options;\n this.parent = parent instanceof _UiComponent ? parent : null;\n this._needsRefresh = false;\n }\n set element(value) {\n this._element = value;\n this._element[0].id = `KS${Object.getPrototypeOf(this).constructor.name}#${this.componentId}`;\n }\n get element() {\n return mustExist(this._element);\n }\n requestRefresh(withChildren = false, depth = 0, trace = false) {\n var _a, _b, _c;\n if (trace) {\n console.debug(\n ...cl(\n depth < 0 ? "⤒".repeat(depth * -1) : " ".repeat(depth),\n this.toString(),\n "requestRefresh()"\n )\n );\n }\n (_b = (_a = this.options) == null ? void 0 : _a.onRefreshRequest) == null ? void 0 : _b.call(this);\n if (this.parent !== this && !withChildren) {\n (_c = this.parent) == null ? void 0 : _c.requestRefresh(false, depth - 1, trace);\n }\n if (this._needsRefresh) {\n if (trace) {\n console.debug(\n ...cl(\n depth < 0 ? "⤒".repeat(depth * -1) : " ".repeat(depth),\n this.toString(),\n "requestRefresh() <already pending>"\n )\n );\n }\n }\n this._needsRefresh = true;\n if (withChildren) {\n if (trace) {\n console.debug(\n ...cl(\n depth < 0 ? "⤒".repeat(depth * -1) : " ".repeat(depth),\n this.toString(),\n "requestRefresh()",\n `+ ${this.children.size} children`\n )\n );\n }\n for (const child of this.children) {\n child.requestRefresh(true, depth + 1, trace);\n }\n } else {\n if (trace) {\n console.debug(\n ...cl(\n depth < 0 ? "⤒".repeat(depth * -1) : " ".repeat(depth),\n this.toString(),\n "requestRefresh()",\n "<queued>"\n )\n );\n }\n }\n }\n refresh(force = false, depth = 0) {\n var _a, _b;\n if (!force && !this._needsRefresh) {\n if (depth === 0) {\n console.debug(...cl(this.toString(), "refresh() received and ignored."));\n }\n return;\n }\n (_b = (_a = this.options) == null ? void 0 : _a.onRefresh) == null ? void 0 : _b.call(this);\n for (const child of this.children) {\n child.refresh(force, depth + 1);\n }\n this._needsRefresh = false;\n }\n addChild(child) {\n child.parent = this;\n this.children.add(child);\n this.element.append(child.element);\n return this;\n }\n addChildren(children) {\n for (const child of children ?? []) {\n this.addChild(child);\n }\n return this;\n }\n removeChild(child) {\n if (!this.children.has(child)) {\n return;\n }\n child.element.remove();\n this.children.delete(child);\n }\n removeChildren(children) {\n for (const child of children) {\n this.removeChild(child);\n }\n }\n };\n __publicField(_UiComponent, "nextComponentId", 0);\n let UiComponent = _UiComponent;\n class Container extends UiComponent {\n /**\n * Constructs a simple container element without any special properties.\n *\n * @param host A reference to the host.\n * @param options Options for the container.\n */\n constructor(parent, options) {\n super(parent, { ...options });\n this.element = $("<div/>");\n for (const className of (options == null ? void 0 : options.classes) ?? []) {\n this.element.addClass(className);\n }\n }\n toString() {\n return `[${Container.name}#${this.componentId}]`;\n }\n }\n const label = "_label_1nlev_1";\n const splitter = "_splitter_1nlev_16";\n const iconLabel = "_iconLabel_1nlev_20";\n const fillSpace = "_fillSpace_1nlev_26";\n const stylesLabelListItem = {\n label,\n splitter,\n iconLabel,\n fillSpace\n };\n const delimiter = "_delimiter_16hnh_1";\n const stylesDelimiter = {\n delimiter\n };\n class ListItem extends UiComponent {\n /**\n * Construct a new simple list item with only a container element.\n *\n * @param host The userscript instance.\n * @param options Options for the list item.\n */\n constructor(parent, options) {\n super(parent, { ...options });\n this.element = $("<li/>");\n for (const className of (options == null ? void 0 : options.classes) ?? []) {\n this.element.addClass(className);\n }\n if ((options == null ? void 0 : options.delimiter) === true) {\n this.element.addClass(stylesDelimiter.delimiter);\n }\n }\n toString() {\n return `[${ListItem.name}#${this.componentId}]`;\n }\n }\n const head = "_head_wr1pj_1";\n const stylesListItem = {\n head\n };\n class LabelListItem extends ListItem {\n /**\n * Construct a new label list item.\n *\n * @param host The userscript instance.\n * @param label The label on the setting element.\n * @param options Options for the list item.\n */\n constructor(parent, label2, options) {\n super(parent, options);\n __publicField(this, "head");\n __publicField(this, "elementLabel");\n this.head = new Container(parent);\n this.head.element.addClass(stylesListItem.head);\n this.addChild(this.head);\n this.elementLabel = $("<label/>", {\n text: `${(options == null ? void 0 : options.upgradeIndicator) === true ? "⮤ " : ""}${label2}`\n }).addClass(stylesLabelListItem.label).addClass(stylesListItem.label);\n this.head.element.append(this.elementLabel);\n if (options == null ? void 0 : options.icon) {\n const iconElement = $("<div/>", {\n html: `<svg style="width: 15px; height: 15px;" viewBox="0 -960 960 960" fill="currentColor"><path d="${options.icon}"/></svg>`\n }).addClass(stylesLabelListItem.iconLabel);\n this.elementLabel.prepend(iconElement);\n }\n }\n toString() {\n return `[${LabelListItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n addChildHead(child) {\n this.head.addChild(child);\n return this;\n }\n addChildrenHead(children) {\n for (const child of children ?? []) {\n this.head.addChild(child);\n }\n return this;\n }\n }\n const setting = "_setting_1ndg5_1";\n const checkbox = "_checkbox_1ndg5_6";\n const panelContent = "_panelContent_1ndg5_10";\n const hidden = "_hidden_1ndg5_17";\n const checked = "_checked_1ndg5_22";\n const expanded$1 = "_expanded_1ndg5_26";\n const readonly$1 = "_readonly_1ndg5_34";\n const stylesSettingListItem = {\n setting,\n checkbox,\n panelContent,\n hidden,\n checked,\n expanded: expanded$1,\n readonly: readonly$1\n };\n class SettingListItem extends LabelListItem {\n /**\n * Construct a new setting element.\n * This is a simple checkbox with a label.\n *\n * @param host The userscript instance.\n * @param label The label on the setting element.\n * @param setting The setting this element is linked to.\n * @param options Options for this list item.\n */\n constructor(parent, setting2, label2, options) {\n super(parent, label2, {\n ...options,\n onRefresh: () => {\n var _a;\n if (this.setting.enabled) {\n this.element.addClass(stylesSettingListItem.checked);\n } else {\n this.element.removeClass(stylesSettingListItem.checked);\n }\n if (this.readOnly) {\n this.element.addClass(stylesSettingListItem.readonly);\n } else {\n this.element.removeClass(stylesSettingListItem.readonly);\n }\n if (!isNil(this.checkbox)) {\n this.checkbox.prop("checked", this.setting.enabled);\n this.checkbox.prop("disabled", this.readOnly);\n }\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(options);\n }\n });\n __publicField(this, "setting");\n __publicField(this, "checkbox");\n __publicField(this, "readOnly");\n this.element.addClass(stylesSettingListItem.setting);\n const id = `ks-setting${this.componentId}`;\n const checkbox2 = $("<input/>", {\n id,\n type: "checkbox"\n }).addClass(stylesSettingListItem.checkbox);\n this.readOnly = (options == null ? void 0 : options.readOnly) ?? false;\n checkbox2.prop("disabled", this.readOnly);\n checkbox2.on("change", (_event) => {\n if (checkbox2.is(":checked") && !setting2.enabled) {\n this.check().catch(redirectErrorsToConsole(console));\n } else if (!checkbox2.is(":checked") && setting2.enabled) {\n this.uncheck().catch(redirectErrorsToConsole(console));\n }\n });\n this.elementLabel.before(checkbox2);\n this.elementLabel.prop("for", id);\n this.checkbox = checkbox2;\n this.setting = setting2;\n }\n toString() {\n return `[${SettingListItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n async check(isBatchProcess = false) {\n var _a, _b;\n this.setting.enabled = true;\n await ((_b = (_a = this.options) == null ? void 0 : _a.onCheck) == null ? void 0 : _b.call(isBatchProcess));\n this.requestRefresh();\n }\n async uncheck(isBatchProcess = false) {\n var _a;\n this.setting.enabled = false;\n await ((_a = this.options.onUnCheck) == null ? void 0 : _a.call(isBatchProcess));\n this.requestRefresh();\n }\n }\n const iconButton = "_iconButton_q7zpt_17";\n const inactive = "_inactive_q7zpt_29";\n const ineffective = "_ineffective_q7zpt_37";\n const button = "_button_q7zpt_43";\n const readonly = "_readonly_q7zpt_67";\n const buttonIcon = "_buttonIcon_q7zpt_72";\n const alignRight = "_alignRight_q7zpt_77";\n const large = "_large_q7zpt_81";\n const bordered = "_bordered_q7zpt_85";\n const headAction = "_headAction_q7zpt_97";\n const lastHeadAction = "_lastHeadAction_q7zpt_100";\n const consumeButton = "_consumeButton_q7zpt_104";\n const stockButton = "_stockButton_q7zpt_107";\n const stylesButton = {\n iconButton,\n inactive,\n ineffective,\n button,\n readonly,\n buttonIcon,\n alignRight,\n large,\n bordered,\n headAction,\n lastHeadAction,\n consumeButton,\n stockButton\n };\n class IconButton extends UiComponent {\n /**\n * Constructs an `IconButton`.\n *\n * @param host A reference to the host.\n * @param pathData The SVG path data of the icon.\n * @param title The `title` of the element.\n * @param options Options for the icon button.\n */\n constructor(parent, pathData, title, options) {\n super(parent, {\n ...options,\n onRefresh: () => {\n var _a;\n if (this.readOnly) {\n this.element.addClass(stylesButton.readonly);\n } else {\n this.element.removeClass(stylesButton.readonly);\n }\n if (this.inactive) {\n this.element.addClass(stylesButton.inactive);\n } else {\n this.element.removeClass(stylesButton.inactive);\n }\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(options);\n }\n });\n __publicField(this, "readOnly");\n __publicField(this, "inactive");\n this.element = $("<div/>", {\n html: `<svg style="width: 18px; height: 18px;" viewBox="0 -960 960 960" fill="currentColor"><path d="${pathData}"/></svg>`,\n title\n }).addClass(stylesButton.iconButton);\n this.readOnly = (options == null ? void 0 : options.readOnly) ?? false;\n this.inactive = (options == null ? void 0 : options.inactive) ?? false;\n this.element.on("click", () => {\n if (this.readOnly) {\n return;\n }\n this.click().catch(redirectErrorsToConsole(console));\n });\n }\n toString() {\n return `[${IconButton.name}#${this.componentId}]`;\n }\n async click() {\n var _a, _b;\n if (this.readOnly) {\n return;\n }\n await ((_b = (_a = this.options) == null ? void 0 : _a.onClick) == null ? void 0 : _b.call(this));\n this.requestRefresh();\n }\n }\n const listContainer = "_listContainer_1kxbq_1";\n const itemsList = "_itemsList_1kxbq_5";\n const list = "_list_1kxbq_1";\n const listTools = "_listTools_1kxbq_9";\n const styles$c = {\n listContainer,\n itemsList,\n list,\n listTools\n };\n class SettingsList extends UiComponent {\n /**\n * Constructs a `SettingsList`.\n *\n * @param host A reference to the host.\n * @param options Which tools should be available on the list?\n */\n constructor(parent, options) {\n super(parent, { ...options });\n __publicField(this, "list");\n __publicField(this, "disableAllButton");\n __publicField(this, "enableAllButton");\n __publicField(this, "resetButton");\n const toolOptions = {\n hasDisableAll: true,\n hasEnableAll: true,\n ...options\n };\n const hasTools = toolOptions.hasDisableAll || toolOptions.hasEnableAll || !isNil(toolOptions.onReset);\n this.element = $("<div/>").addClass(styles$c.listContainer);\n this.list = $("<ul/>").addClass(styles$c.list).addClass(styles$c.itemsList);\n this.element.append(this.list);\n if (hasTools) {\n const tools = new Container(this, { classes: [styles$c.listTools] });\n if (toolOptions.hasEnableAll) {\n this.enableAllButton = new IconButton(\n parent,\n Icons.CheckboxCheck,\n parent.host.engine.i18n("ui.enable.all"),\n {\n onClick: async () => {\n var _a;\n const event = new Event("enableAll", { cancelable: true });\n this.element[0].dispatchEvent(event);\n if (event.defaultPrevented) {\n return;\n }\n for (const child of this.children) {\n if (is(child, SettingListItem)) {\n await child.check(true);\n }\n }\n (_a = options == null ? void 0 : options.onEnableAll) == null ? void 0 : _a.call(this);\n }\n }\n );\n tools.addChild(this.enableAllButton);\n }\n if (toolOptions.hasDisableAll) {\n this.disableAllButton = new IconButton(\n parent,\n Icons.CheckboxUnCheck,\n parent.host.engine.i18n("ui.disable.all"),\n {\n onClick: async () => {\n var _a;\n const event = new Event("disableAll", { cancelable: true });\n this.element[0].dispatchEvent(event);\n if (event.defaultPrevented) {\n return;\n }\n for (const child of this.children) {\n if (is(child, SettingListItem)) {\n await child.uncheck(true);\n }\n }\n (_a = options == null ? void 0 : options.onDisableAll) == null ? void 0 : _a.call(this);\n }\n }\n );\n tools.addChild(this.disableAllButton);\n }\n const onReset = toolOptions.onReset;\n if (!isNil(onReset)) {\n this.resetButton = new IconButton(\n parent,\n Icons.Reset,\n parent.host.engine.i18n("ui.reset"),\n {\n onClick: () => {\n onReset();\n }\n }\n );\n tools.addChild(this.resetButton);\n }\n super.addChild(tools);\n }\n }\n toString() {\n return `[${SettingsList.name}#${this.componentId}]`;\n }\n addChild(child) {\n child.parent = this;\n this.children.add(child);\n this.list.append(child.element);\n return this;\n }\n }\n const expandoButton = "_expandoButton_l1ukp_1";\n const expanded = "_expanded_l1ukp_1";\n const up = "_up_l1ukp_1";\n const down = "_down_l1ukp_4";\n const styles$b = {\n expandoButton,\n expanded,\n up,\n down\n };\n class ExpandoButton extends UiComponent {\n /**\n * Constructs an expando element that is commonly used to expand and\n * collapses a section of the UI.\n *\n * @param host A reference to the host.\n * @param options Options for this expando.\n */\n constructor(parent, options) {\n super(parent, {\n ...options,\n onRefresh: () => {\n var _a;\n if (this.ineffective) {\n this.element.addClass(stylesButton.ineffective);\n } else {\n this.element.removeClass(stylesButton.ineffective);\n }\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(options);\n }\n });\n __publicField(this, "readOnly");\n __publicField(this, "inactive");\n __publicField(this, "ineffective");\n this.element = $("<div/>", {\n html: `\n <svg style="width: 18px; height: 18px;" viewBox="0 -960 960 960" fill="currentColor" class="${styles$b.down}"><path d="${Icons.ExpandCircleDown}"/></svg>\n <svg style="width: 18px; height: 18px;" viewBox="0 -960 960 960" fill="currentColor" class="${styles$b.up}"><path d="${Icons.ExpandCircleUp}"/></svg>\n `,\n title: parent.host.engine.i18n("ui.itemsShow")\n }).addClass(stylesButton.iconButton).addClass(styles$b.expandoButton);\n this.element.on("click", () => {\n if (this.readOnly) {\n return;\n }\n this.click().catch(redirectErrorsToConsole(console));\n });\n this.readOnly = (options == null ? void 0 : options.readOnly) ?? false;\n this.inactive = (options == null ? void 0 : options.inactive) ?? false;\n this.ineffective = false;\n }\n toString() {\n return `[${ExpandoButton.name}#${this.componentId}]`;\n }\n setCollapsed() {\n this.element.removeClass(styles$b.expanded);\n this.element.prop("title", this.host.engine.i18n("ui.itemsShow"));\n }\n setExpanded() {\n this.element.addClass(styles$b.expanded);\n this.element.prop("title", this.host.engine.i18n("ui.itemsHide"));\n }\n async click() {\n var _a, _b;\n if (this.readOnly) {\n return;\n }\n await ((_b = (_a = this.options) == null ? void 0 : _a.onClick) == null ? void 0 : _b.call(this));\n this.requestRefresh();\n }\n }\n class CollapsiblePanel extends UiComponent {\n /**\n * Constructs a settings panel that is used to contain a single child element.\n *\n * @param host A reference to the host.\n * @param head Another component to host in the head of the panel.\n * @param options Options for this panel.\n */\n constructor(parent, head2, options) {\n super(parent, options);\n __publicField(this, "container");\n __publicField(this, "expando");\n __publicField(this, "head");\n __publicField(this, "_mainChildVisible");\n this.head = head2;\n this.container = new Container(this);\n this.container.element.addClass(stylesSettingListItem.panelContent);\n const expando = new ExpandoButton(parent, {\n onClick: () => this.toggle()\n });\n head2.head.addChild(expando);\n head2.element.append(this.container.element);\n if (options == null ? void 0 : options.initiallyExpanded) {\n this.container.element.removeClass(stylesSettingListItem.hidden);\n expando.setExpanded();\n } else {\n this.container.element.addClass(stylesSettingListItem.hidden);\n }\n this._mainChildVisible = (options == null ? void 0 : options.initiallyExpanded) ?? false;\n this.element = head2.element;\n this.expando = expando;\n this.addChildren([this.head, this.container]);\n }\n get isExpanded() {\n return this._mainChildVisible;\n }\n toString() {\n return `[${CollapsiblePanel.name}#${this.componentId}]`;\n }\n addChildHead(child) {\n this.head.addChild(child);\n return this;\n }\n addChildrenHead(children) {\n for (const child of children ?? []) {\n this.head.addChild(child);\n }\n return this;\n }\n addChildContent(child) {\n this.container.addChild(child);\n return this;\n }\n addChildrenContent(children) {\n for (const child of children ?? []) {\n this.container.addChild(child);\n }\n return this;\n }\n /**\n * Control the visibility of the panel\'s contents.\n *\n * @param expand Should the panel be expanded? If not set, the panel is toggled.\n * @param toggleNested Also toggle all panels inside this panel?\n */\n toggle(expand = void 0, toggleNested = false) {\n const visible = expand !== void 0 ? expand : !this._mainChildVisible;\n if (visible !== this._mainChildVisible) {\n this._mainChildVisible = visible;\n if (this._mainChildVisible) {\n this.container.requestRefresh(true);\n this.container.element.removeClass(stylesSettingListItem.hidden);\n this.expando.setExpanded();\n this.head.element.addClass(stylesSettingListItem.expanded);\n this.element[0].dispatchEvent(new CustomEvent("panelShown"));\n } else {\n this.container.element.addClass(stylesSettingListItem.hidden);\n this.expando.setCollapsed();\n this.head.element.removeClass(stylesSettingListItem.expanded);\n this.element[0].dispatchEvent(new CustomEvent("panelHidden"));\n }\n }\n if (toggleNested) {\n const toggleChildren = (children) => {\n for (const child of children) {\n if (is(child, CollapsiblePanel)) {\n child.toggle(expand, toggleNested);\n } else {\n toggleChildren(child.children);\n }\n }\n };\n toggleChildren(this.children);\n }\n }\n }\n class SettingsPanel extends CollapsiblePanel {\n /**\n * Constructs a settings panel that is used to contain a major section of the UI.\n *\n * @param host - A reference to the host.\n * @param settingItem - The UI element to be placed in the head of the panel.\n * @param setting - An setting for which this is the settings panel.\n * @param options - Options for this panel.\n */\n constructor(parent, setting2, settingItem, options) {\n super(parent, settingItem, options);\n __publicField(this, "setting");\n __publicField(this, "settingItem");\n this.element = settingItem.element;\n this.settingItem = settingItem;\n this.setting = setting2;\n }\n get isExpanded() {\n return this._mainChildVisible;\n }\n // SettingListItem interface\n get elementLabel() {\n return this.head.element;\n }\n get readOnly() {\n return true;\n }\n set readOnly(_value) {\n }\n async check() {\n this.setting.enabled = true;\n this.requestRefresh();\n }\n async uncheck() {\n this.setting.enabled = false;\n this.requestRefresh();\n }\n toString() {\n return `[${SettingsPanel.name}#${this.componentId}]: \'${this.settingItem.elementLabel.text()}\'`;\n }\n }\n class BuildingUpgradeSettingsUi extends SettingsPanel {\n constructor(parent, settings, _locale, sectionSetting) {\n const label2 = parent.host.engine.i18n("ui.upgrade.buildings");\n super(\n parent,\n settings,\n new SettingListItem(parent, settings, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]),\n {\n onRefreshRequest: () => {\n this.expando.ineffective = sectionSetting.enabled && settings.enabled && !Object.values(settings.buildings).some((building) => building.enabled);\n }\n }\n );\n const items = [];\n for (const setting2 of Object.values(this.setting.buildings)) {\n const label22 = this.host.engine.i18n(`$buildings.${setting2.upgrade}.label`);\n const button2 = new SettingListItem(this, setting2, label22, {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [label22]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [label22]);\n }\n });\n items.push({ button: button2, label: label22 });\n }\n items.sort((a, b) => a.label.localeCompare(b.label));\n const itemsList2 = new SettingsList(this);\n for (const button2 of items) {\n itemsList2.addChild(button2.button);\n }\n this.addChildContent(itemsList2);\n }\n }\n class Button extends UiComponent {\n /**\n * Constructs a `Button`.\n *\n * @param host - A reference to the host.\n * @param label - The text to display on the button.\n * @param pathData - The SVG path data of the icon.\n * @param options - Options for the icon button.\n */\n constructor(parent, label2, pathData = null, options) {\n super(parent, {\n ...options,\n onRefresh: () => {\n var _a;\n if (this.readOnly) {\n this.element.addClass(stylesButton.readonly);\n } else {\n this.element.removeClass(stylesButton.readonly);\n }\n if (this.inactive) {\n this.element.addClass(stylesButton.inactive);\n } else {\n this.element.removeClass(stylesButton.inactive);\n }\n if (this.ineffective) {\n this.element.addClass(stylesButton.ineffective);\n } else {\n this.element.removeClass(stylesButton.ineffective);\n }\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(options);\n }\n });\n __publicField(this, "_iconElement");\n __publicField(this, "readOnly");\n __publicField(this, "inactive");\n __publicField(this, "ineffective");\n this.element = $("<div/>", { title: options == null ? void 0 : options.title }).addClass(stylesButton.button).text(label2);\n if ((options == null ? void 0 : options.border) !== false) {\n this.element.addClass(stylesButton.bordered);\n }\n if ((options == null ? void 0 : options.alignment) === "right") {\n this.element.addClass(stylesButton.alignRight);\n }\n if (pathData !== null) {\n this._iconElement = $(\n `<svg class="${stylesButton.buttonIcon}" style="width: 18px; height: 18px;" viewBox="0 -960 960 960" fill="currentColor"><path d="${pathData}"/></svg>`\n );\n if ((options == null ? void 0 : options.alignment) === "right") {\n this.element.append(this._iconElement);\n } else {\n this.element.prepend(this._iconElement);\n }\n }\n for (const className of (options == null ? void 0 : options.classes) ?? []) {\n this.element.addClass(className);\n }\n this.element.on("click", () => {\n if (this.readOnly) {\n return;\n }\n this.click().catch(redirectErrorsToConsole(console));\n });\n this.readOnly = (options == null ? void 0 : options.readOnly) ?? false;\n this.inactive = (options == null ? void 0 : options.inactive) ?? false;\n this.ineffective = false;\n }\n toString() {\n return `[${Button.name}#${this.componentId}]`;\n }\n updateLabel(label2) {\n this.element.text(label2);\n if (this._iconElement !== void 0) {\n if (this.options.alignment === "right") {\n this.element.append(this._iconElement);\n } else {\n this.element.prepend(this._iconElement);\n }\n }\n }\n updateTitle(title) {\n this.element.prop("title", title);\n }\n async click() {\n var _a, _b;\n if (this.readOnly) {\n return;\n }\n await ((_b = (_a = this.options) == null ? void 0 : _a.onClick) == null ? void 0 : _b.call(this));\n this.requestRefresh();\n }\n }\n class Delimiter extends UiComponent {\n /**\n * Constructs a `Delimiter`.\n *\n * @param host A reference to the host.\n * @param label The label on the fieldset.\n * @param options Options for the fieldset.\n */\n constructor(parent) {\n super(parent, {});\n this.element = $("<div/>").addClass(stylesDelimiter.delimiter);\n }\n toString() {\n return `[${Delimiter.name}#${this.componentId}]`;\n }\n }\n const dialog = "_dialog_1276o_1";\n const close = "_close_1276o_7";\n const styles$a = {\n dialog,\n close\n };\n const explainer = "_explainer_1idu3_1";\n const styles$9 = {\n explainer\n };\n const header = "_header_19ql8_1";\n const styles$8 = {\n header\n };\n class HeaderListItem extends UiComponent {\n get elementLabel() {\n return this.element;\n }\n /**\n * Construct an informational text item.\n * This is purely for cosmetic/informational value in the UI.\n *\n * @param host A reference to the host.\n * @param text The text to appear on the header element.\n * @param options Options for the header.\n */\n constructor(parent, text, options) {\n super(parent, { ...options });\n this.element = $("<li/>", { text }).addClass(styles$8.header);\n }\n toString() {\n return `[${HeaderListItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n }\n class Input extends UiComponent {\n /**\n * Constructs an input field.\n *\n * @param host - A reference to the host.\n * @param label - The label on the input element.\n * @param options - Options for the UI element.\n */\n constructor(parent, options) {\n super(parent, { ...options });\n this.element = $(\'<input type="text"/>\').addClass("ks-input");\n for (const className of (options == null ? void 0 : options.classes) ?? []) {\n this.element.addClass(className);\n }\n if (options == null ? void 0 : options.onChange) {\n this.element.on("change", () => {\n var _a;\n return (_a = options.onChange) == null ? void 0 : _a.call(options, this.element[0].value);\n });\n }\n if (options == null ? void 0 : options.value) {\n this.element[0].value = options.value;\n }\n if (options == null ? void 0 : options.selected) {\n this.element[0].selectionStart = 0;\n this.element[0].selectionEnd = -1;\n }\n this.element.on("keyup", (event) => {\n var _a, _b;\n switch (event.key) {\n case "Enter":\n (_a = options == null ? void 0 : options.onEnter) == null ? void 0 : _a.call(options, this.element[0].value);\n break;\n case "Escape":\n (_b = options == null ? void 0 : options.onEscape) == null ? void 0 : _b.call(options, this.element[0].value);\n break;\n }\n });\n }\n toString() {\n return `[${Input.name}#${this.componentId}]`;\n }\n }\n class Paragraph extends UiComponent {\n /**\n * Constructs a paragraph.\n *\n * @param host - A reference to the host.\n * @param text - The text inside the paragraph.\n * @param options - Options for the UI element.\n */\n constructor(parent, text, options) {\n super(parent, { ...options });\n this.element = $("<p/>").text(text);\n for (const className of (options == null ? void 0 : options.classes) ?? []) {\n this.element.addClass(className);\n }\n }\n toString() {\n return `[${Paragraph.name}#${this.componentId}]`;\n }\n }\n const toolbar = "_toolbar_1654f_1";\n const styles$7 = {\n toolbar\n };\n class Dialog extends UiComponent {\n /**\n * Constructs a dialog.\n *\n * @param host - A reference to the host.\n * @param options - Options for the dialog.\n */\n constructor(parent, options) {\n super(parent, { ...options });\n __publicField(this, "container");\n __publicField(this, "head");\n __publicField(this, "returnValue");\n this.element = $("<dialog/>").addClass("dialog").addClass("help").addClass(styles$a.dialog);\n if ((options == null ? void 0 : options.hasClose) !== false) {\n this.addChild(\n new Button(parent, "close", null, {\n classes: [styles$a.close],\n onClick: () => {\n var _a;\n this.close();\n (_a = options == null ? void 0 : options.onCancel) == null ? void 0 : _a.call(options);\n }\n })\n );\n }\n this.returnValue = (options == null ? void 0 : options.promptValue) ?? "";\n this.head = new Container(parent);\n this.container = new Container(parent);\n this.addChildren(\n coalesceArray([\n this.head,\n (options == null ? void 0 : options.prompt) ? new Input(parent, {\n onChange: (value) => {\n this.returnValue = value;\n },\n onEnter: (value) => {\n var _a;\n this.returnValue = value;\n this.close();\n (_a = options.onConfirm) == null ? void 0 : _a.call(options, this.returnValue);\n },\n onEscape: (_value) => {\n var _a;\n this.close();\n (_a = options.onCancel) == null ? void 0 : _a.call(options);\n },\n selected: true,\n value: options.promptValue\n }) : void 0,\n this.container,\n new Delimiter(parent),\n new Container(parent, {\n classes: [styles$7.toolbar]\n }).addChildren(\n coalesceArray([\n new Button(parent, "OK", null, {\n classes: [stylesButton.large],\n onClick: () => {\n var _a;\n this.close();\n (_a = options == null ? void 0 : options.onConfirm) == null ? void 0 : _a.call(options, this.returnValue);\n }\n }),\n (options == null ? void 0 : options.hasCancel) ? new Button(parent, "Cancel", null, {\n classes: [stylesButton.large],\n onClick: () => {\n var _a;\n this.close();\n (_a = options.onCancel) == null ? void 0 : _a.call(options);\n }\n }) : void 0\n ])\n )\n ])\n );\n }\n toString() {\n return `[${Dialog.name}#${this.componentId}]`;\n }\n addChildHead(child) {\n this.head.addChild(child);\n return this;\n }\n addChildrenHead(children) {\n for (const child of children ?? []) {\n this.head.addChild(child);\n }\n return this;\n }\n addChildContent(child) {\n this.container.addChild(child);\n return this;\n }\n addChildrenContent(children) {\n for (const child of children ?? []) {\n this.container.addChild(child);\n }\n return this;\n }\n show() {\n $("#gamePageContainer").append(this.element);\n this.element[0].show();\n }\n showModal() {\n $("#gamePageContainer").append(this.element);\n this.element[0].showModal();\n }\n close() {\n this.element[0].close();\n this.element.remove();\n }\n static async prompt(parent, text, title, initialValue, explainer2) {\n return new Promise((resolve) => {\n new Dialog(parent, {\n hasCancel: true,\n hasClose: false,\n onCancel: () => {\n resolve(void 0);\n },\n onConfirm: (result) => {\n resolve(result);\n },\n prompt: true,\n promptValue: initialValue\n }).addChildrenHead(\n coalesceArray([\n title ? new HeaderListItem(parent, title) : void 0,\n new Paragraph(parent, text)\n ])\n ).addChildrenContent(\n explainer2 ? [\n new Container(parent, {\n classes: [styles$9.explainer]\n }).addChildren([new Paragraph(parent, explainer2)])\n ] : []\n ).showModal();\n });\n }\n }\n const maxButton = "_maxButton_133h2_1";\n const styles$6 = {\n maxButton\n };\n class MaxButton extends Button {\n constructor(parent, setting2, options) {\n super(parent, "", null, {\n ...options,\n classes: [styles$6.maxButton, ...(options == null ? void 0 : options.classes) ?? []]\n });\n __publicField(this, "setting");\n this.setting = setting2;\n }\n toString() {\n return `[${MaxButton.name}#${this.componentId}]`;\n }\n }\n class TriggerButton extends Button {\n constructor(parent, setting2, _locale, options) {\n super(parent, "", Icons.Trigger, {\n ...options,\n onRefresh: () => {\n var _a, _b;\n const triggerValue = this.behavior === "integer" ? this.host.renderAbsolute(this.setting.trigger, "invariant") : this.host.renderPercentage(this.setting.trigger, "invariant", true);\n this.updateTitle(this.host.engine.i18n("ui.trigger", [triggerValue]));\n if (((_a = this.options) == null ? void 0 : _a.renderLabel) ?? true) {\n this.updateLabel(triggerValue);\n }\n if (!this.inactive) {\n this.element.removeClass(stylesButton.inactive);\n } else {\n this.element.addClass(stylesButton.inactive);\n }\n (_b = options == null ? void 0 : options.onRefresh) == null ? void 0 : _b.call(this);\n }\n });\n __publicField(this, "behavior");\n __publicField(this, "setting");\n this.behavior = setting2 instanceof SettingTrigger ? "percentage" : "integer";\n this.setting = setting2;\n }\n toString() {\n return `[${TriggerButton.name}#${this.componentId}]`;\n }\n }\n class SettingMaxTriggerListItem extends SettingListItem {\n constructor(parent, setting2, locale, label2, options) {\n super(parent, setting2, label2, options);\n __publicField(this, "maxButton");\n __publicField(this, "triggerButton");\n this.maxButton = new MaxButton(parent, setting2, {\n alignment: "right",\n border: false,\n classes: [stylesButton.headAction],\n onClick: async () => {\n await options.onSetMax.call(this);\n },\n onRefresh: (options == null ? void 0 : options.onRefreshMax) ? () => {\n var _a;\n return (_a = options.onRefreshMax) == null ? void 0 : _a.call(this);\n } : void 0\n });\n this.triggerButton = new TriggerButton(parent, setting2, locale, {\n border: false,\n classes: [stylesButton.lastHeadAction],\n onClick: async () => {\n await options.onSetTrigger.call(this);\n },\n onRefresh: (options == null ? void 0 : options.onRefreshTrigger) ? () => {\n var _a;\n return (_a = options.onRefreshTrigger) == null ? void 0 : _a.call(this);\n } : void 0,\n renderLabel: (options == null ? void 0 : options.renderLabelTrigger) ?? true\n });\n this.addChildrenHead([\n new Container(parent, { classes: [stylesLabelListItem.fillSpace] }),\n this.maxButton,\n this.triggerButton\n ]);\n }\n toString() {\n return `[${SettingMaxTriggerListItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n }\n const BuildSectionTools = {\n getBuildOption: (parent, option, locale, sectionSetting, label2, sectionLabel, options) => {\n const onSetMax = async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.max.prompt.absolute"),\n parent.host.engine.i18n("ui.max.build.prompt", [\n label2,\n parent.host.renderAbsolute(option.max, locale.selected)\n ]),\n parent.host.renderAbsolute(option.max),\n parent.host.engine.i18n("ui.max.build.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.max = -1;\n return;\n }\n if (value === "0") {\n option.enabled = false;\n }\n option.max = parent.host.parseAbsolute(value) ?? option.max;\n };\n const element = new SettingMaxTriggerListItem(parent, option, locale, label2, {\n delimiter: options == null ? void 0 : options.delimiter,\n onCheck: async (isBatchProcess) => {\n var _a;\n parent.host.engine.imessage("status.sub.enable", [label2]);\n if (option.max === 0 && !isBatchProcess) {\n await onSetMax();\n }\n await ((_a = options == null ? void 0 : options.onCheck) == null ? void 0 : _a.call(options, isBatchProcess));\n },\n onRefreshMax: () => {\n element.maxButton.updateLabel(parent.host.renderAbsolute(option.max));\n element.maxButton.element[0].title = option.max < 0 ? parent.host.engine.i18n("ui.max.build.titleInfinite", [label2]) : option.max === 0 ? parent.host.engine.i18n("ui.max.build.titleZero", [label2]) : parent.host.engine.i18n("ui.max.build.title", [\n parent.host.renderAbsolute(option.max),\n label2\n ]);\n },\n onRefreshRequest: () => {\n element.maxButton.inactive = !option.enabled || option.max === -1;\n element.maxButton.ineffective = sectionSetting.enabled && option.enabled && option.max === 0;\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = sectionSetting.enabled && option.enabled && sectionSetting.trigger === -1 && option.trigger === -1;\n },\n onRefreshTrigger: () => {\n element.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger", [\n option.trigger < 0 ? sectionSetting.trigger < 0 ? parent.host.engine.i18n("ui.trigger.build.blocked", [sectionLabel]) : `${parent.host.renderPercentage(sectionSetting.trigger, locale.selected, true)} (${parent.host.engine.i18n("ui.trigger.build.inherited")})` : parent.host.renderPercentage(option.trigger, locale.selected, true)\n ]);\n },\n onSetMax,\n onSetTrigger: async () => {\n var _a;\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.build.prompt", [\n label2,\n option.trigger !== -1 ? parent.host.renderPercentage(option.trigger, locale.selected, true) : parent.host.engine.i18n("ui.trigger.build.inherited")\n ]),\n option.trigger !== -1 ? parent.host.renderPercentage(option.trigger) : "",\n parent.host.engine.i18n("ui.trigger.build.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n return;\n }\n option.trigger = parent.host.parsePercentage(value);\n await ((_a = options == null ? void 0 : options.onSetTrigger) == null ? void 0 : _a.call(void 0));\n },\n onUnCheck: (isBatchProcess) => {\n var _a;\n parent.host.engine.imessage("status.sub.disable", [label2]);\n (_a = options == null ? void 0 : options.onUnCheck) == null ? void 0 : _a.call(options, isBatchProcess);\n },\n renderLabelTrigger: options == null ? void 0 : options.renderLabelTrigger,\n upgradeIndicator: options == null ? void 0 : options.upgradeIndicator\n });\n return element;\n }\n };\n class SettingTriggerListItem extends SettingListItem {\n constructor(parent, setting2, locale, label2, options) {\n super(parent, setting2, label2, options);\n __publicField(this, "triggerButton");\n this.triggerButton = new TriggerButton(parent, setting2, locale, {\n alignment: "right",\n border: false,\n onClick: async () => {\n await options.onSetTrigger.call(this);\n },\n onRefresh: (options == null ? void 0 : options.onRefreshTrigger) ? () => {\n var _a;\n return (_a = options.onRefreshTrigger) == null ? void 0 : _a.call(this);\n } : void 0,\n renderLabel: (options == null ? void 0 : options.renderLabelTrigger) ?? true\n });\n this.addChildrenHead([\n new Container(parent, { classes: [stylesLabelListItem.fillSpace] }),\n this.triggerButton\n ]);\n }\n toString() {\n return `[${SettingTriggerListItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n }\n class BonfireSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${BonfireSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.build");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefreshTrigger: () => {\n this.settingItem.triggerButton.element[0].title = parent.host.engine.i18n(\n "ui.trigger.section",\n [\n settings.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.inactive") : parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]\n );\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger, locale.selected, true) : parent.host.engine.i18n("ui.infinity")\n ]),\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.trigger = -1;\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger < 0;\n this.settingItem.triggerButton.ineffective = settings.enabled && settings.trigger < 0 && Object.values(settings.buildings).some((_) => _.enabled && 0 < _.max && _.trigger < 0);\n this.expando.ineffective = settings.enabled && Object.values(settings.buildings).some(\n (_) => _.enabled && (0 === _.max || _.trigger < 0 && settings.trigger < 0)\n );\n }\n }\n );\n this.addChildrenContent([\n new SettingsList(this, {\n onReset: () => {\n this.setting.load({ buildings: new BonfireSettings().buildings });\n }\n }).addChildren(\n coalesceArray(\n this.host.game.bld.buildingGroups.flatMap((buildingGroup) => [\n new HeaderListItem(this, buildingGroup.title),\n ...buildingGroup.buildings.flatMap(\n (building) => this._getBuildOptions(this, settings, locale, label2, building)\n ),\n buildingGroup !== this.host.game.bld.buildingGroups[this.host.game.bld.buildingGroups.length - 1] ? new Delimiter(this) : void 0\n ])\n )\n ),\n new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([\n new HeaderListItem(this, this.host.engine.i18n("ui.additional")),\n new SettingListItem(this, settings.gatherCatnip, this.host.engine.i18n("option.catnip"), {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.catnip")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.catnip")\n ]);\n }\n }),\n new SettingListItem(\n this,\n settings.turnOnSteamworks,\n this.host.engine.i18n("option.steamworks"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.steamworks")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.steamworks")\n ]);\n }\n }\n ),\n new SettingListItem(\n this,\n settings.turnOnMagnetos,\n this.host.engine.i18n("option.magnetos"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.magnetos")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.magnetos")\n ]);\n }\n }\n ),\n new SettingListItem(\n this,\n settings.turnOnReactors,\n this.host.engine.i18n("option.reactors"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.reactors")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.reactors")\n ]);\n }\n }\n ),\n new BuildingUpgradeSettingsUi(this, settings.upgradeBuildings, locale, settings)\n ])\n ]);\n }\n _getBuildOptions(parent, settings, locale, sectionLabel, building) {\n var _a;\n if (building === "unicornPasture" || isNil(settings.buildings[building])) {\n return [];\n }\n const meta = parent.host.game.bld.getBuildingExt(building).meta;\n if (!isNil(meta.stages)) {\n const name = (_a = Object.values(settings.buildings).find((item) => item.baseBuilding === building)) == null ? void 0 : _a.building;\n return [\n BuildSectionTools.getBuildOption(\n parent,\n settings.buildings[building],\n locale,\n settings,\n meta.stages[0].label,\n sectionLabel,\n { renderLabelTrigger: false }\n ),\n BuildSectionTools.getBuildOption(\n parent,\n settings.buildings[name],\n locale,\n settings,\n meta.stages[1].label,\n sectionLabel,\n {\n renderLabelTrigger: false,\n upgradeIndicator: true\n }\n )\n ];\n }\n if (!isNil(meta.label)) {\n return [\n BuildSectionTools.getBuildOption(\n parent,\n settings.buildings[building],\n locale,\n settings,\n meta.label,\n sectionLabel,\n { renderLabelTrigger: false }\n )\n ];\n }\n return [];\n }\n }\n class EngineSettingsUi extends SettingListItem {\n constructor(parent, settings) {\n const label2 = ucfirst(parent.host.engine.i18n("ui.engine"));\n super(parent, settings, label2, {\n onCheck: () => {\n parent.host.engine.start(true);\n },\n onUnCheck: () => {\n parent.host.engine.stop(true);\n }\n });\n __publicField(this, "expando");\n this.expando = new ExpandoButton(this);\n this.addChildrenHead([\n new Container(parent, { classes: [stylesLabelListItem.fillSpace] }),\n this.expando\n ]);\n }\n }\n class ButtonListItem extends ListItem {\n constructor(parent, button2, options) {\n super(parent, { ...options });\n __publicField(this, "button");\n this.button = button2;\n this.element.addClass(stylesListItem.head);\n this.element.append(button2.element);\n }\n }\n const fieldset = "_fieldset_tfwil_1";\n const styles$5 = {\n fieldset\n };\n class Fieldset extends UiComponent {\n /**\n * Constructs a `Fieldset`.\n *\n * @param host A reference to the host.\n * @param label The label on the fieldset.\n * @param options Options for the fieldset.\n */\n constructor(parent, label2, options) {\n super(parent, { ...options });\n this.element = $("<fieldset/>").addClass(styles$5.fieldset);\n if (options == null ? void 0 : options.delimiter) {\n this.element.addClass(stylesDelimiter.delimiter);\n }\n const legend = $("<legend/>").text(label2).addClass(stylesLabelListItem.label);\n this.element.append(legend);\n }\n toString() {\n return `[${Fieldset.name}#${this.componentId}]`;\n }\n }\n class RadioItem extends UiComponent {\n /**\n * Construct a new radio setting element.\n * This is a radio input that is expected to be hosted in a `Fieldset`.\n *\n * @param host The userscript instance.\n * @param setting The setting this element is linked to.\n * @param option The specific option out of the setting that this radio item represents.\n * @param groupKey A unique name for the group of radio items this one belongs to.\n * @param options Options for this radio item.\n */\n constructor(parent, setting2, option, groupKey, options) {\n super(parent, {\n ...options,\n onRefresh: () => {\n this.input.prop("disabled", this.readOnly);\n }\n });\n __publicField(this, "setting");\n __publicField(this, "option");\n __publicField(this, "elementLabel");\n __publicField(this, "input");\n __publicField(this, "readOnly");\n this.element = $("<div/>");\n this.element.addClass(stylesSettingListItem.setting);\n if ((options == null ? void 0 : options.delimiter) === true) {\n this.element.addClass(stylesDelimiter.delimiter);\n }\n this.elementLabel = $("<label/>", {\n text: `${(options == null ? void 0 : options.upgradeIndicator) ? "⮤ " : ""}${option.label}`\n }).addClass(stylesLabelListItem.label);\n const input = $("<input/>", {\n name: groupKey,\n type: "radio"\n }).addClass("ks-radio");\n this.readOnly = (options == null ? void 0 : options.readOnly) ?? false;\n input.on("change", () => {\n this.setting.selected = option.value;\n if (!isNil(options == null ? void 0 : options.onCheck)) {\n options.onCheck();\n }\n });\n this.elementLabel.prepend(input);\n this.element.append(this.elementLabel);\n this.input = input;\n this.setting = setting2;\n this.option = option;\n }\n toString() {\n return `[${RadioItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n }\n class OptionsListItem extends UiComponent {\n /**\n * Construct a new options setting element.\n * This is a list of options, where the selected option will be put into the setting.\n *\n * @param host The userscript instance.\n * @param label The label on the setting element.\n * @param setting The setting this element is linked to.\n * @param options Options for the list item.\n */\n constructor(parent, label2, setting2, options) {\n super(parent, {\n ...options,\n onRefresh: () => {\n var _a;\n for (const option of this._items) {\n if (option.option.value === this.setting.selected) {\n option.input.prop("checked", true);\n break;\n }\n }\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(options);\n }\n });\n __publicField(this, "fieldset");\n __publicField(this, "setting");\n __publicField(this, "_items");\n this.element = $("<li/>");\n this.fieldset = new Fieldset(parent, label2);\n this.addChild(this.fieldset);\n this._items = new Array();\n for (const option of setting2.options) {\n this._items.push(\n new RadioItem(parent, setting2, option, label2, {\n onCheck: options == null ? void 0 : options.onCheck,\n readOnly: options == null ? void 0 : options.readOnly\n })\n );\n }\n this.fieldset.addChildren(this._items);\n this.setting = setting2;\n }\n toString() {\n return `[${OptionsListItem.name}#${this.componentId}]`;\n }\n }\n const textButton = "_textButton_1mv97_1";\n const styles$4 = {\n textButton\n };\n class TextButton extends UiComponent {\n constructor(parent, label2, options) {\n super(parent, {\n ...options,\n onRefresh: () => {\n var _a;\n if (this.readOnly) {\n this.element.addClass(stylesButton.readonly);\n } else {\n this.element.removeClass(stylesButton.readonly);\n }\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(this);\n }\n });\n __publicField(this, "readOnly");\n this.element = $("<div/>").addClass(styles$4.textButton);\n if (label2 !== void 0) {\n this.element.text(label2);\n }\n const title = options == null ? void 0 : options.title;\n if (!isNil(title)) {\n this.element.prop("title", title);\n }\n this.readOnly = false;\n this.element.on("click", () => {\n if (this.readOnly) {\n return;\n }\n this.click().catch(redirectErrorsToConsole(console));\n });\n }\n toString() {\n return `[${TextButton.name}#${this.componentId}]`;\n }\n async click() {\n var _a, _b;\n if (this.readOnly) {\n return;\n }\n await ((_b = (_a = this.options) == null ? void 0 : _a.onClick) == null ? void 0 : _b.call(this));\n this.requestRefresh();\n }\n }\n class InternalsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${InternalsUi.name}`));\n super(\n parent,\n settings,\n new LabelListItem(parent, parent.host.engine.i18n("ui.internals"), {\n classes: [stylesSettingListItem.checked, stylesSettingListItem.setting],\n icon: Icons.Settings\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })])\n );\n this.addChildrenContent([\n new SettingsList(parent, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([\n new ButtonListItem(\n parent,\n new TextButton(\n parent,\n parent.host.engine.i18n("ui.internals.interval", [settings.interval]),\n {\n onClick: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.internals.interval.prompt"),\n parent.host.engine.i18n("ui.internals.interval.promptTitle", [\n parent.host.renderAbsolute(settings.interval, locale.selected)\n ]),\n parent.host.renderAbsolute(settings.interval),\n parent.host.engine.i18n("ui.internals.interval.promptExplainer")\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n if (value === "0") {\n settings.enabled = false;\n }\n settings.interval = parent.host.parseAbsolute(value) ?? settings.interval;\n },\n onRefresh() {\n this.element.text(\n parent.host.engine.i18n("ui.internals.interval", [settings.interval])\n );\n }\n }\n )\n ),\n new Delimiter(parent),\n new SettingListItem(parent, settings.ksColumn, parent.host.engine.i18n("ui.ksColumn"), {\n onCheck: () => {\n parent.host.rebuildUi();\n },\n onUnCheck: () => {\n parent.host.rebuildUi();\n }\n }),\n new Delimiter(parent),\n new OptionsListItem(parent, parent.host.engine.i18n("ui.language"), settings.locale, {\n onCheck: () => {\n parent.host.rebuildUi();\n }\n }),\n new Delimiter(parent),\n new LabelListItem(parent, `Kitten Scientists ${ksVersion("v")}`)\n ])\n ]);\n }\n }\n class ExplainerListItem extends UiComponent {\n /**\n * Construct an element to explain an area of the UI.\n * This is purely for cosmetic/informational value in the UI.\n *\n * @param host - A reference to the host.\n * @param key - The i18n key for the text to appear on the element.\n * @param options - Options for this explainer.\n */\n constructor(parent, key, options) {\n super(parent, { ...options });\n this.element = $("<li/>", { text: parent.host.engine.i18n(key) }).addClass(styles$9.explainer);\n }\n toString() {\n return `[${ExplainerListItem.name}#${this.componentId}]`;\n }\n }\n class LogFiltersSettingsUi extends SettingsPanel {\n constructor(parent, settings) {\n console.debug(...cl(`Constructing ${LogFiltersSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.filter");\n super(\n parent,\n settings,\n new SettingListItem(parent, settings, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })])\n );\n this.addChildContent(\n new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([\n new SettingListItem(this, settings.disableKGLog, this.host.engine.i18n("filter.allKG"))\n ])\n );\n const listFilters = new SettingsList(this).addChildren(\n FilterItems.map((item) => {\n return { label: this.host.engine.i18n(`filter.${item}`), name: item };\n }).sort((a, b) => a.label.localeCompare(b.label)).map(\n (item) => new SettingListItem(this, this.setting.filters[item.name], item.label, {\n onCheck: () => {\n this.host.engine.imessage("filter.enable", [item.label]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("filter.disable", [item.label]);\n }\n })\n )\n );\n this.addChildContent(listFilters);\n this.addChildContent(new ExplainerListItem(this, "filter.explainer"));\n }\n }\n const active = "_active_6c09s_16";\n const styles$3 = {\n active\n };\n class ReligionSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${ReligionSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.faith");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefreshTrigger() {\n this.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger.section", [\n settings.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.inactive") : parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger, locale.selected, true) : parent.host.engine.i18n("ui.infinity")\n ]),\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.trigger = -1;\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefresh: () => {\n for (const [buildingName, building] of this._unicornBuildings.entries()) {\n building.elementLabel.attr("data-ks-active-from", "❊");\n building.elementLabel.attr("data-ks-active-to", "✮");\n if (this.setting.bestUnicornBuilding.enabled && this.setting.bestUnicornBuildingCurrent === buildingName) {\n building.elementLabel.addClass(styles$3.active);\n } else {\n building.elementLabel.removeClass(styles$3.active);\n }\n }\n },\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger === -1;\n this.settingItem.triggerButton.ineffective = settings.enabled && settings.trigger < 0 && Object.values(settings.buildings).some((_) => _.enabled && 0 < _.max && _.trigger < 0);\n this.expando.ineffective = settings.enabled && Object.values(settings.buildings).some(\n (_) => _.enabled && (0 === _.max || _.trigger < 0 && settings.trigger < 0)\n );\n for (const [_, building] of this._unicornBuildings.entries()) {\n building.readOnly = this._bestUnicornBuilding.setting.enabled;\n building.maxButton.readOnly = this._bestUnicornBuilding.setting.enabled;\n building.triggerButton.readOnly = this._bestUnicornBuilding.setting.enabled;\n }\n }\n }\n );\n __publicField(this, "_unicornBuildings");\n __publicField(this, "_bestUnicornBuilding");\n const unicornsArray = [...UnicornItems];\n this._unicornBuildings = new Map([\n [\n "unicornPasture",\n BuildSectionTools.getBuildOption(\n this,\n this.setting.buildings.unicornPasture,\n locale,\n this.setting,\n this.host.engine.i18n("$buildings.unicornPasture.label"),\n label2,\n { renderLabelTrigger: false }\n )\n ],\n ...this.host.game.religion.zigguratUpgrades.filter(\n (item) => unicornsArray.includes(item.name) && !isNil(this.setting.buildings[item.name])\n ).map(\n (zigguratUpgrade) => [\n zigguratUpgrade.name,\n BuildSectionTools.getBuildOption(\n this,\n this.setting.buildings[zigguratUpgrade.name],\n locale,\n this.setting,\n zigguratUpgrade.label,\n label2,\n { renderLabelTrigger: false }\n )\n ]\n )\n ]);\n this._bestUnicornBuilding = new SettingListItem(\n this,\n this.setting.bestUnicornBuilding,\n this.host.engine.i18n("option.faith.best.unicorn"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.faith.best.unicorn")\n ]);\n for (const building of this._unicornBuildings.values()) {\n building.setting.enabled = true;\n building.setting.max = -1;\n building.setting.trigger = -1;\n }\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.faith.best.unicorn")\n ]);\n },\n upgradeIndicator: true\n }\n );\n this.addChildrenContent([\n new SettingsList(this, {\n onReset: () => {\n const defaults = new ReligionSettings();\n this.setting.load({\n bestUnicornBuilding: defaults.bestUnicornBuilding,\n buildings: defaults.buildings\n });\n }\n }).addChildren([\n new HeaderListItem(this, this.host.engine.i18n("$religion.panel.ziggurat.label")),\n ...this._unicornBuildings.values(),\n this._bestUnicornBuilding,\n new Delimiter(this),\n ...this.host.game.religion.zigguratUpgrades.filter(\n (item) => !unicornsArray.includes(item.name) && !isNil(this.setting.buildings[item.name])\n ).map(\n (upgrade) => BuildSectionTools.getBuildOption(\n this,\n this.setting.buildings[upgrade.name],\n locale,\n this.setting,\n upgrade.label,\n label2,\n { renderLabelTrigger: false }\n )\n ),\n new Delimiter(this),\n new HeaderListItem(this, this.host.engine.i18n("$religion.panel.orderOfTheSun.label")),\n ...this.host.game.religion.religionUpgrades.filter((item) => !isNil(this.setting.buildings[item.name])).map(\n (upgrade) => {\n var _a;\n return BuildSectionTools.getBuildOption(\n this,\n this.setting.buildings[upgrade.name],\n locale,\n this.setting,\n upgrade.label,\n label2,\n {\n delimiter: upgrade.name === ((_a = this.host.game.religion.religionUpgrades.at(-1)) == null ? void 0 : _a.name),\n renderLabelTrigger: false\n }\n );\n }\n ),\n new HeaderListItem(this, this.host.engine.i18n("$religion.panel.cryptotheology.label")),\n ...this.host.game.religion.transcendenceUpgrades.filter((item) => !isNil(this.setting.buildings[item.name])).map(\n (upgrade) => BuildSectionTools.getBuildOption(\n this,\n this.setting.buildings[upgrade.name],\n locale,\n this.setting,\n upgrade.label,\n label2,\n { renderLabelTrigger: false }\n )\n )\n ]),\n new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([\n new HeaderListItem(this, this.host.engine.i18n("ui.additional")),\n ...ReligionOptions.map((item) => {\n const label22 = this.host.engine.i18n(`option.faith.${item}`);\n if (item === "transcend") {\n return new SettingListItem(this, this.setting[item], label22, {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [label22]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [label22]);\n }\n });\n }\n const element = new SettingTriggerListItem(this, this.setting[item], locale, label22, {\n classes: [stylesButton.lastHeadAction],\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [label22]);\n },\n onRefresh: () => {\n element.triggerButton.inactive = !this.setting[item].enabled || this.setting[item].trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n(\n element.triggerButton.behavior === "integer" ? "ui.trigger.setinteger" : "ui.trigger.setpercentage",\n [label22]\n ),\n this.host.engine.i18n("ui.trigger.build.prompt", [\n label22,\n element.triggerButton.behavior === "integer" ? this.host.renderAbsolute(this.setting[item].trigger, locale.selected) : this.host.renderPercentage(this.setting[item].trigger, locale.selected, true)\n ]),\n element.triggerButton.behavior === "integer" ? this.host.renderAbsolute(this.setting[item].trigger) : this.host.renderPercentage(this.setting[item].trigger),\n this.host.engine.i18n(\n element.triggerButton.behavior === "integer" ? "ui.trigger.setinteger.promptExplainer" : "ui.trigger.setpercentage.promptExplainer"\n )\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n this.setting[item].trigger = (element.triggerButton.behavior === "integer" ? this.host.parseAbsolute(value) : this.host.parsePercentage(value)) ?? this.setting[item].trigger;\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [label22]);\n }\n });\n element.triggerButton.element.addClass(stylesButton.lastHeadAction);\n return element;\n })\n ])\n ]);\n }\n }\n class ConsumeButton extends Button {\n constructor(parent, setting2, locale, resourceName, options) {\n super(parent, "", Icons.DataUsage, {\n ...options,\n onClick: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("resources.consume.prompt"),\n parent.host.engine.i18n("resources.consume.promptTitle", [\n resourceName,\n parent.host.renderPercentage(setting2.consume, locale.selected, true)\n ]),\n parent.host.renderPercentage(setting2.consume),\n parent.host.engine.i18n("resources.consume.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n return;\n }\n setting2.consume = parent.host.parsePercentage(value);\n },\n onRefresh: () => {\n var _a;\n const consumeValue = this.host.renderPercentage(\n this.setting.consume,\n this.host.engine.settings.locale.selected,\n true\n );\n const title = this.setting.consume === 0 ? this.host.engine.i18n("resources.consume.titleZero", [this.resourceName]) : this.host.engine.i18n("resources.consume.title", [consumeValue, this.resourceName]);\n this.updateTitle(title);\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(options);\n }\n });\n __publicField(this, "setting");\n __publicField(this, "resourceName");\n this.element.addClass(stylesButton.consumeButton);\n this.resourceName = resourceName;\n this.setting = setting2;\n }\n toString() {\n return `[${ConsumeButton.name}#${this.componentId}]`;\n }\n }\n class StockButton extends Button {\n constructor(parent, setting2, locale, resourceName, options) {\n super(parent, "", null, {\n ...options,\n onClick: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("resources.stock.prompt"),\n parent.host.engine.i18n("resources.stock.promptTitle", [\n resourceName,\n parent.host.renderAbsolute(setting2.stock, locale.selected)\n ]),\n parent.host.renderAbsolute(setting2.stock),\n parent.host.engine.i18n("resources.stock.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n setting2.stock = -1;\n return;\n }\n if (value === "0") {\n setting2.enabled = false;\n }\n setting2.stock = parent.host.parseAbsolute(value) ?? setting2.stock;\n },\n onRefresh: () => {\n const stockValue = this.host.renderAbsolute(this.setting.stock);\n const title = this.setting.stock < 0 ? this.host.engine.i18n("resources.stock.titleInfinite", [this.resourceName]) : this.setting.stock === 0 ? this.host.engine.i18n("resources.stock.titleZero", [this.resourceName]) : this.host.engine.i18n("resources.stock.title", [\n this.host.renderAbsolute(this.setting.stock),\n this.resourceName\n ]);\n this.updateTitle(title);\n this.updateLabel(stockValue);\n }\n });\n __publicField(this, "setting");\n __publicField(this, "resourceName");\n this.element.addClass(stylesButton.stockButton);\n this.resourceName = resourceName;\n this.setting = setting2;\n }\n toString() {\n return `[${StockButton.name}#${this.componentId}]`;\n }\n }\n class ResourcesSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${ResourcesSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.resources");\n super(\n parent,\n settings,\n new LabelListItem(parent, label2, {\n classes: [stylesSettingListItem.checked, stylesSettingListItem.setting],\n icon: Icons.Resources\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })])\n );\n const ignoredResources = [\n "blackcoin",\n "burnedParagon",\n "elderBox",\n "gflops",\n "hashrates",\n "kittens",\n "paragon",\n "temporalFlux",\n "wrappingPaper",\n "zebras"\n ];\n this.addChildContent(\n new SettingsList(this).addChildren(\n this.host.game.resPool.resources.filter(\n (item) => !ignoredResources.includes(item.name) && !isNil(this.setting.resources[item.name])\n ).sort((a, b) => a.title.localeCompare(b.title, locale.selected)).map(\n (resource) => [this.setting.resources[resource.name], ucfirst(resource.title)]\n ).map(([setting2, title]) => this._makeResourceSetting(this, setting2, locale, title))\n )\n );\n }\n /**\n * Creates a UI element that reflects stock and consume values for a given resource.\n * This is currently only used for the craft section.\n *\n * @param label The title to apply to the option.\n * @param option The option that is being controlled.\n * @returns A new option with stock and consume values.\n */\n _makeResourceSetting(parent, option, locale, label2) {\n const element = new SettingListItem(parent, option, label2, {\n onCheck: () => {\n parent.host.engine.imessage("status.resource.enable", [label2]);\n },\n onUnCheck: () => {\n parent.host.engine.imessage("status.resource.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]);\n const stockElement = new StockButton(parent, option, locale, label2, {\n alignment: "right",\n border: false,\n classes: [stylesButton.headAction],\n onRefreshRequest: () => {\n stockElement.inactive = !option.enabled || option.stock === 0;\n }\n });\n element.head.addChild(stockElement);\n const consumeElement = new ConsumeButton(parent, option, locale, label2, {\n border: false,\n classes: [stylesButton.lastHeadAction],\n onRefreshRequest: () => {\n consumeElement.inactive = !option.enabled || option.consume !== 100;\n consumeElement.ineffective = option.enabled && option.consume === 0;\n }\n });\n element.head.addChild(consumeElement);\n return element;\n }\n }\n class PolicySettingsUi extends SettingsPanel {\n constructor(parent, settings, locale, sectionSetting) {\n const label2 = parent.host.engine.i18n("ui.upgrade.policies");\n super(\n parent,\n settings,\n new SettingListItem(parent, settings, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]),\n {\n onRefreshRequest: () => {\n this.expando.ineffective = sectionSetting.enabled && settings.enabled && !Object.values(settings.policies).some((policy) => policy.enabled);\n }\n }\n );\n const policies = this.host.game.science.policies.filter(\n (policy) => !isNil(this.setting.policies[policy.name])\n );\n const items = [];\n let lastLabel = policies[0].label;\n for (const policy of policies.sort((a, b) => a.label.localeCompare(b.label, locale.selected))) {\n const option = this.setting.policies[policy.name];\n const element = new SettingListItem(this, option, policy.label, {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [policy.label]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [policy.label]);\n }\n });\n if (this.host.engine.localeSupportsFirstLetterSplits(locale.selected)) {\n if (lastLabel[0] !== policy.label[0]) {\n element.element.addClass(stylesLabelListItem.splitter);\n }\n }\n items.push(element);\n lastLabel = policy.label;\n }\n this.addChildContent(new SettingsList(this).addChildren(items));\n }\n }\n class TechSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale, sectionSetting) {\n const label2 = parent.host.engine.i18n("ui.upgrade.techs");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefreshTrigger() {\n this.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger", [\n settings.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.inactive") : parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger, locale.selected, true) : parent.host.engine.i18n("ui.infinity")\n ]),\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.trigger = -1;\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger === -1;\n this.settingItem.triggerButton.ineffective = sectionSetting.enabled && settings.enabled && settings.trigger === -1 && !Object.values(settings.techs).some((tech) => tech.enabled && 0 <= tech.trigger);\n this.expando.ineffective = sectionSetting.enabled && settings.enabled && !Object.values(settings.techs).some((tech) => tech.enabled);\n }\n }\n );\n const techs = this.host.game.science.techs.filter(\n (tech) => !isNil(this.setting.techs[tech.name])\n );\n const items = [];\n let lastLabel = techs[0].label;\n for (const tech of techs.sort((a, b) => a.label.localeCompare(b.label, locale.selected))) {\n const option = this.setting.techs[tech.name];\n const element = new SettingTriggerListItem(this, option, locale, tech.label, {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [tech.label]);\n },\n onRefresh: () => {\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = sectionSetting.enabled && settings.enabled && option.enabled && settings.trigger === -1 && option.trigger === -1;\n },\n onRefreshTrigger: () => {\n element.triggerButton.element[0].title = this.host.engine.i18n("ui.trigger", [\n option.trigger < 0 ? settings.trigger < 0 ? this.host.engine.i18n("ui.trigger.section.blocked", [label2]) : `${this.host.renderPercentage(settings.trigger, locale.selected, true)} (${this.host.engine.i18n("ui.trigger.section.inherited")})` : this.host.renderPercentage(option.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.trigger.prompt.percentage"),\n this.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n option.trigger !== -1 ? this.host.renderPercentage(option.trigger, locale.selected, true) : this.host.engine.i18n("ui.trigger.section.inherited")\n ]),\n option.trigger !== -1 ? this.host.renderPercentage(option.trigger) : "",\n this.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n return;\n }\n option.trigger = this.host.parsePercentage(value);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [tech.label]);\n },\n renderLabelTrigger: false\n });\n element.triggerButton.element.addClass(stylesButton.lastHeadAction);\n if (this.host.engine.localeSupportsFirstLetterSplits(locale.selected)) {\n if (lastLabel[0] !== tech.label[0]) {\n element.element.addClass(stylesLabelListItem.splitter);\n }\n }\n items.push(element);\n lastLabel = tech.label;\n }\n this.addChildContent(new SettingsList(this).addChildren(items));\n }\n }\n class ScienceSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${ScienceSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.upgrade");\n super(\n parent,\n settings,\n new SettingListItem(parent, settings, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]),\n {\n onRefresh: () => {\n if (this.setting.observe.enabled) {\n $("#observeButton").hide();\n } else {\n $("#observeButton").show();\n }\n },\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && (this.setting.policies.enabled && this._policiesUi.expando.ineffective || this.setting.techs.enabled && (this._techsUi.expando.ineffective || this._techsUi.settingItem.triggerButton.ineffective));\n }\n }\n );\n __publicField(this, "_policiesUi");\n __publicField(this, "_techsUi");\n __publicField(this, "_observeStars");\n this._policiesUi = new PolicySettingsUi(this, settings.policies, locale, settings);\n this._techsUi = new TechSettingsUi(this, settings.techs, locale, settings);\n this._observeStars = new SettingListItem(\n this,\n this.setting.observe,\n this.host.engine.i18n("option.observe"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [this.host.engine.i18n("option.observe")]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.observe")\n ]);\n }\n }\n );\n const itemsList2 = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n });\n itemsList2.addChildren([this._techsUi, this._policiesUi, this._observeStars]);\n this.addChildContent(itemsList2);\n }\n }\n class MissionSettingsUi extends SettingsPanel {\n constructor(parent, settings, _locale, sectionSetting) {\n const label2 = parent.host.engine.i18n("ui.upgrade.missions");\n super(\n parent,\n settings,\n new SettingListItem(parent, settings, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefresh: () => {\n this.expando.ineffective = sectionSetting.enabled && settings.enabled && !Object.values(settings.missions).some((mission) => mission.enabled);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })])\n );\n __publicField(this, "_missions");\n this._missions = this.host.game.space.programs.filter((item) => !isNil(this.setting.missions[item.name])).map(\n (mission) => new SettingListItem(this, this.setting.missions[mission.name], mission.label, {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [mission.label]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [mission.label]);\n }\n })\n );\n const itemsList2 = new SettingsList(this).addChildren(this._missions);\n this.addChildContent(itemsList2);\n }\n }\n class SpaceSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${SpaceSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.space");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefreshTrigger() {\n this.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger.section", [\n settings.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.inactive") : parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger, locale.selected, true) : parent.host.engine.i18n("ui.infinity")\n ]),\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.trigger = -1;\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger === -1;\n this.settingItem.triggerButton.ineffective = settings.enabled && settings.trigger < 0 && Object.values(settings.buildings).some((_) => _.enabled && 0 < _.max && _.trigger < 0);\n this.expando.ineffective = settings.enabled && (Object.values(settings.buildings).some(\n (_) => _.enabled && (0 === _.max || _.trigger < 0 && settings.trigger < 0)\n ) || !Object.values(settings.buildings).some((_) => _.enabled) && !settings.unlockMissions.enabled || this._missionsUi.expando.ineffective);\n }\n }\n );\n __publicField(this, "_missionsUi");\n this.addChildContent(\n new SettingsList(this, {\n onReset: () => {\n this.setting.load({ buildings: new SpaceSettings().buildings });\n }\n }).addChildren(\n this.host.game.space.planets.filter((planet) => 0 < planet.buildings.length).flatMap((planet, indexPlanet, arrayPlant) => [\n new HeaderListItem(this, this.host.engine.labelForPlanet(planet.name)),\n ...planet.buildings.filter((item) => !isNil(this.setting.buildings[item.name])).map(\n (building, indexBuilding, arrayBuilding) => BuildSectionTools.getBuildOption(\n this,\n this.setting.buildings[building.name],\n locale,\n this.setting,\n building.label,\n label2,\n {\n delimiter: indexPlanet < arrayPlant.length - 1 && indexBuilding === arrayBuilding.length - 1,\n renderLabelTrigger: false\n }\n )\n )\n ])\n )\n );\n const listAddition = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n });\n listAddition.addChild(new HeaderListItem(this, this.host.engine.i18n("ui.additional")));\n this._missionsUi = new MissionSettingsUi(\n this,\n this.setting.unlockMissions,\n locale,\n this.setting\n );\n listAddition.addChild(this._missionsUi);\n this.addChildContent(listAddition);\n }\n }\n class InvalidArgumentError extends AbstractError {\n /**\n * Constructs a new {@linkcode InvalidArgumentError}.\n * @param message - The main error message.\n * @param status - The HTTP status code to return.\n */\n constructor(message, status = 400) {\n super("ERR_OS_INVALID_ARGUMENT", message, status);\n this.name = "InvalidArgumentError";\n if (typeof Error.captureStackTrace !== "undefined") {\n Error.captureStackTrace(this, InvalidArgumentError);\n }\n }\n }\n const minutesInMonth = 43200;\n const minutesInDay = 1440;\n const constructFromSymbol = Symbol.for("constructDateFrom");\n function constructFrom(date, value) {\n if (typeof date === "function") return date(value);\n if (date && typeof date === "object" && constructFromSymbol in date)\n return date[constructFromSymbol](value);\n if (date instanceof Date) return new date.constructor(value);\n return new Date(value);\n }\n function constructNow(date) {\n return constructFrom(date, Date.now());\n }\n const formatDistanceLocale$3 = {\n lessThanXSeconds: {\n one: "less than a second",\n other: "less than {{count}} seconds"\n },\n xSeconds: {\n one: "1 second",\n other: "{{count}} seconds"\n },\n halfAMinute: "half a minute",\n lessThanXMinutes: {\n one: "less than a minute",\n other: "less than {{count}} minutes"\n },\n xMinutes: {\n one: "1 minute",\n other: "{{count}} minutes"\n },\n aboutXHours: {\n one: "about 1 hour",\n other: "about {{count}} hours"\n },\n xHours: {\n one: "1 hour",\n other: "{{count}} hours"\n },\n xDays: {\n one: "1 day",\n other: "{{count}} days"\n },\n aboutXWeeks: {\n one: "about 1 week",\n other: "about {{count}} weeks"\n },\n xWeeks: {\n one: "1 week",\n other: "{{count}} weeks"\n },\n aboutXMonths: {\n one: "about 1 month",\n other: "about {{count}} months"\n },\n xMonths: {\n one: "1 month",\n other: "{{count}} months"\n },\n aboutXYears: {\n one: "about 1 year",\n other: "about {{count}} years"\n },\n xYears: {\n one: "1 year",\n other: "{{count}} years"\n },\n overXYears: {\n one: "over 1 year",\n other: "over {{count}} years"\n },\n almostXYears: {\n one: "almost 1 year",\n other: "almost {{count}} years"\n }\n };\n const formatDistance$4 = (token, count, options) => {\n let result;\n const tokenValue = formatDistanceLocale$3[token];\n if (typeof tokenValue === "string") {\n result = tokenValue;\n } else if (count === 1) {\n result = tokenValue.one;\n } else {\n result = tokenValue.other.replace("{{count}}", count.toString());\n }\n if (options == null ? void 0 : options.addSuffix) {\n if (options.comparison && options.comparison > 0) {\n return "in " + result;\n } else {\n return result + " ago";\n }\n }\n return result;\n };\n function buildFormatLongFn(args) {\n return (options = {}) => {\n const width = options.width ? String(options.width) : args.defaultWidth;\n const format = args.formats[width] || args.formats[args.defaultWidth];\n return format;\n };\n }\n const dateFormats$3 = {\n full: "EEEE, MMMM do, y",\n long: "MMMM do, y",\n medium: "MMM d, y",\n short: "MM/dd/yyyy"\n };\n const timeFormats$3 = {\n full: "h:mm:ss a zzzz",\n long: "h:mm:ss a z",\n medium: "h:mm:ss a",\n short: "h:mm a"\n };\n const dateTimeFormats$3 = {\n full: "{{date}} \'at\' {{time}}",\n long: "{{date}} \'at\' {{time}}",\n medium: "{{date}}, {{time}}",\n short: "{{date}}, {{time}}"\n };\n const formatLong$3 = {\n date: buildFormatLongFn({\n formats: dateFormats$3,\n defaultWidth: "full"\n }),\n time: buildFormatLongFn({\n formats: timeFormats$3,\n defaultWidth: "full"\n }),\n dateTime: buildFormatLongFn({\n formats: dateTimeFormats$3,\n defaultWidth: "full"\n })\n };\n const formatRelativeLocale$3 = {\n lastWeek: "\'last\' eeee \'at\' p",\n yesterday: "\'yesterday at\' p",\n today: "\'today at\' p",\n tomorrow: "\'tomorrow at\' p",\n nextWeek: "eeee \'at\' p",\n other: "P"\n };\n const formatRelative$3 = (token, _date, _baseDate, _options2) => formatRelativeLocale$3[token];\n function buildLocalizeFn(args) {\n return (value, options) => {\n const context = (options == null ? void 0 : options.context) ? String(options.context) : "standalone";\n let valuesArray;\n if (context === "formatting" && args.formattingValues) {\n const defaultWidth = args.defaultFormattingWidth || args.defaultWidth;\n const width = (options == null ? void 0 : options.width) ? String(options.width) : defaultWidth;\n valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth];\n } else {\n const defaultWidth = args.defaultWidth;\n const width = (options == null ? void 0 : options.width) ? String(options.width) : args.defaultWidth;\n valuesArray = args.values[width] || args.values[defaultWidth];\n }\n const index = args.argumentCallback ? args.argumentCallback(value) : value;\n return valuesArray[index];\n };\n }\n const eraValues$3 = {\n narrow: ["B", "A"],\n abbreviated: ["BC", "AD"],\n wide: ["Before Christ", "Anno Domini"]\n };\n const quarterValues$3 = {\n narrow: ["1", "2", "3", "4"],\n abbreviated: ["Q1", "Q2", "Q3", "Q4"],\n wide: ["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"]\n };\n const monthValues$3 = {\n narrow: ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"],\n abbreviated: [\n "Jan",\n "Feb",\n "Mar",\n "Apr",\n "May",\n "Jun",\n "Jul",\n "Aug",\n "Sep",\n "Oct",\n "Nov",\n "Dec"\n ],\n wide: [\n "January",\n "February",\n "March",\n "April",\n "May",\n "June",\n "July",\n "August",\n "September",\n "October",\n "November",\n "December"\n ]\n };\n const dayValues$3 = {\n narrow: ["S", "M", "T", "W", "T", "F", "S"],\n short: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],\n abbreviated: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],\n wide: [\n "Sunday",\n "Monday",\n "Tuesday",\n "Wednesday",\n "Thursday",\n "Friday",\n "Saturday"\n ]\n };\n const dayPeriodValues$3 = {\n narrow: {\n am: "a",\n pm: "p",\n midnight: "mi",\n noon: "n",\n morning: "morning",\n afternoon: "afternoon",\n evening: "evening",\n night: "night"\n },\n abbreviated: {\n am: "AM",\n pm: "PM",\n midnight: "midnight",\n noon: "noon",\n morning: "morning",\n afternoon: "afternoon",\n evening: "evening",\n night: "night"\n },\n wide: {\n am: "a.m.",\n pm: "p.m.",\n midnight: "midnight",\n noon: "noon",\n morning: "morning",\n afternoon: "afternoon",\n evening: "evening",\n night: "night"\n }\n };\n const formattingDayPeriodValues$3 = {\n narrow: {\n am: "a",\n pm: "p",\n midnight: "mi",\n noon: "n",\n morning: "in the morning",\n afternoon: "in the afternoon",\n evening: "in the evening",\n night: "at night"\n },\n abbreviated: {\n am: "AM",\n pm: "PM",\n midnight: "midnight",\n noon: "noon",\n morning: "in the morning",\n afternoon: "in the afternoon",\n evening: "in the evening",\n night: "at night"\n },\n wide: {\n am: "a.m.",\n pm: "p.m.",\n midnight: "midnight",\n noon: "noon",\n morning: "in the morning",\n afternoon: "in the afternoon",\n evening: "in the evening",\n night: "at night"\n }\n };\n const ordinalNumber$3 = (dirtyNumber, _options2) => {\n const number = Number(dirtyNumber);\n const rem100 = number % 100;\n if (rem100 > 20 || rem100 < 10) {\n switch (rem100 % 10) {\n case 1:\n return number + "st";\n case 2:\n return number + "nd";\n case 3:\n return number + "rd";\n }\n }\n return number + "th";\n };\n const localize$3 = {\n ordinalNumber: ordinalNumber$3,\n era: buildLocalizeFn({\n values: eraValues$3,\n defaultWidth: "wide"\n }),\n quarter: buildLocalizeFn({\n values: quarterValues$3,\n defaultWidth: "wide",\n argumentCallback: (quarter) => quarter - 1\n }),\n month: buildLocalizeFn({\n values: monthValues$3,\n defaultWidth: "wide"\n }),\n day: buildLocalizeFn({\n values: dayValues$3,\n defaultWidth: "wide"\n }),\n dayPeriod: buildLocalizeFn({\n values: dayPeriodValues$3,\n defaultWidth: "wide",\n formattingValues: formattingDayPeriodValues$3,\n defaultFormattingWidth: "wide"\n })\n };\n function buildMatchFn(args) {\n return (string, options = {}) => {\n const width = options.width;\n const matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth];\n const matchResult = string.match(matchPattern);\n if (!matchResult) {\n return null;\n }\n const matchedString = matchResult[0];\n const parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth];\n const key = Array.isArray(parsePatterns) ? findIndex(parsePatterns, (pattern) => pattern.test(matchedString)) : (\n // [TODO] -- I challenge you to fix the type\n findKey(parsePatterns, (pattern) => pattern.test(matchedString))\n );\n let value;\n value = args.valueCallback ? args.valueCallback(key) : key;\n value = options.valueCallback ? (\n // [TODO] -- I challenge you to fix the type\n options.valueCallback(value)\n ) : value;\n const rest = string.slice(matchedString.length);\n return { value, rest };\n };\n }\n function findKey(object, predicate) {\n for (const key in object) {\n if (Object.prototype.hasOwnProperty.call(object, key) && predicate(object[key])) {\n return key;\n }\n }\n return void 0;\n }\n function findIndex(array, predicate) {\n for (let key = 0; key < array.length; key++) {\n if (predicate(array[key])) {\n return key;\n }\n }\n return void 0;\n }\n function buildMatchPatternFn(args) {\n return (string, options = {}) => {\n const matchResult = string.match(args.matchPattern);\n if (!matchResult) return null;\n const matchedString = matchResult[0];\n const parseResult = string.match(args.parsePattern);\n if (!parseResult) return null;\n let value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0];\n value = options.valueCallback ? options.valueCallback(value) : value;\n const rest = string.slice(matchedString.length);\n return { value, rest };\n };\n }\n const matchOrdinalNumberPattern$3 = /^(\\d+)(th|st|nd|rd)?/i;\n const parseOrdinalNumberPattern$3 = /\\d+/i;\n const matchEraPatterns$3 = {\n narrow: /^(b|a)/i,\n abbreviated: /^(b\\.?\\s?c\\.?|b\\.?\\s?c\\.?\\s?e\\.?|a\\.?\\s?d\\.?|c\\.?\\s?e\\.?)/i,\n wide: /^(before christ|before common era|anno domini|common era)/i\n };\n const parseEraPatterns$3 = {\n any: [/^b/i, /^(a|c)/i]\n };\n const matchQuarterPatterns$3 = {\n narrow: /^[1234]/i,\n abbreviated: /^q[1234]/i,\n wide: /^[1234](th|st|nd|rd)? quarter/i\n };\n const parseQuarterPatterns$3 = {\n any: [/1/i, /2/i, /3/i, /4/i]\n };\n const matchMonthPatterns$3 = {\n narrow: /^[jfmasond]/i,\n abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,\n wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i\n };\n const parseMonthPatterns$3 = {\n narrow: [\n /^j/i,\n /^f/i,\n /^m/i,\n /^a/i,\n /^m/i,\n /^j/i,\n /^j/i,\n /^a/i,\n /^s/i,\n /^o/i,\n /^n/i,\n /^d/i\n ],\n any: [\n /^ja/i,\n /^f/i,\n /^mar/i,\n /^ap/i,\n /^may/i,\n /^jun/i,\n /^jul/i,\n /^au/i,\n /^s/i,\n /^o/i,\n /^n/i,\n /^d/i\n ]\n };\n const matchDayPatterns$3 = {\n narrow: /^[smtwf]/i,\n short: /^(su|mo|tu|we|th|fr|sa)/i,\n abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,\n wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i\n };\n const parseDayPatterns$3 = {\n narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],\n any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i]\n };\n const matchDayPeriodPatterns$3 = {\n narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,\n any: /^([ap]\\.?\\s?m\\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i\n };\n const parseDayPeriodPatterns$3 = {\n any: {\n am: /^a/i,\n pm: /^p/i,\n midnight: /^mi/i,\n noon: /^no/i,\n morning: /morning/i,\n afternoon: /afternoon/i,\n evening: /evening/i,\n night: /night/i\n }\n };\n const match$3 = {\n ordinalNumber: buildMatchPatternFn({\n matchPattern: matchOrdinalNumberPattern$3,\n parsePattern: parseOrdinalNumberPattern$3,\n valueCallback: (value) => parseInt(value, 10)\n }),\n era: buildMatchFn({\n matchPatterns: matchEraPatterns$3,\n defaultMatchWidth: "wide",\n parsePatterns: parseEraPatterns$3,\n defaultParseWidth: "any"\n }),\n quarter: buildMatchFn({\n matchPatterns: matchQuarterPatterns$3,\n defaultMatchWidth: "wide",\n parsePatterns: parseQuarterPatterns$3,\n defaultParseWidth: "any",\n valueCallback: (index) => index + 1\n }),\n month: buildMatchFn({\n matchPatterns: matchMonthPatterns$3,\n defaultMatchWidth: "wide",\n parsePatterns: parseMonthPatterns$3,\n defaultParseWidth: "any"\n }),\n day: buildMatchFn({\n matchPatterns: matchDayPatterns$3,\n defaultMatchWidth: "wide",\n parsePatterns: parseDayPatterns$3,\n defaultParseWidth: "any"\n }),\n dayPeriod: buildMatchFn({\n matchPatterns: matchDayPeriodPatterns$3,\n defaultMatchWidth: "any",\n parsePatterns: parseDayPeriodPatterns$3,\n defaultParseWidth: "any"\n })\n };\n const enUS = {\n code: "en-US",\n formatDistance: formatDistance$4,\n formatLong: formatLong$3,\n formatRelative: formatRelative$3,\n localize: localize$3,\n match: match$3,\n options: {\n weekStartsOn: 0,\n firstWeekContainsDate: 1\n }\n };\n let defaultOptions = {};\n function getDefaultOptions() {\n return defaultOptions;\n }\n function toDate(argument, context) {\n return constructFrom(context || argument, argument);\n }\n function getTimezoneOffsetInMilliseconds(date) {\n const _date = toDate(date);\n const utcDate = new Date(\n Date.UTC(\n _date.getFullYear(),\n _date.getMonth(),\n _date.getDate(),\n _date.getHours(),\n _date.getMinutes(),\n _date.getSeconds(),\n _date.getMilliseconds()\n )\n );\n utcDate.setUTCFullYear(_date.getFullYear());\n return +date - +utcDate;\n }\n function normalizeDates(context, ...dates) {\n const normalize = constructFrom.bind(\n null,\n context || dates.find((date) => typeof date === "object")\n );\n return dates.map(normalize);\n }\n function compareAsc(dateLeft, dateRight) {\n const diff = +toDate(dateLeft) - +toDate(dateRight);\n if (diff < 0) return -1;\n else if (diff > 0) return 1;\n return diff;\n }\n function differenceInCalendarMonths(laterDate, earlierDate, options) {\n const [laterDate_, earlierDate_] = normalizeDates(\n options == null ? void 0 : options.in,\n laterDate,\n earlierDate\n );\n const yearsDiff = laterDate_.getFullYear() - earlierDate_.getFullYear();\n const monthsDiff = laterDate_.getMonth() - earlierDate_.getMonth();\n return yearsDiff * 12 + monthsDiff;\n }\n function endOfDay(date, options) {\n const _date = toDate(date, options == null ? void 0 : options.in);\n _date.setHours(23, 59, 59, 999);\n return _date;\n }\n function endOfMonth(date, options) {\n const _date = toDate(date, options == null ? void 0 : options.in);\n const month = _date.getMonth();\n _date.setFullYear(_date.getFullYear(), month + 1, 0);\n _date.setHours(23, 59, 59, 999);\n return _date;\n }\n function isLastDayOfMonth(date, options) {\n const _date = toDate(date, options == null ? void 0 : options.in);\n return +endOfDay(_date, options) === +endOfMonth(_date, options);\n }\n function differenceInMonths(laterDate, earlierDate, options) {\n const [laterDate_, workingLaterDate, earlierDate_] = normalizeDates(\n options == null ? void 0 : options.in,\n laterDate,\n laterDate,\n earlierDate\n );\n const sign = compareAsc(workingLaterDate, earlierDate_);\n const difference2 = Math.abs(\n differenceInCalendarMonths(workingLaterDate, earlierDate_)\n );\n if (difference2 < 1) return 0;\n if (workingLaterDate.getMonth() === 1 && workingLaterDate.getDate() > 27)\n workingLaterDate.setDate(30);\n workingLaterDate.setMonth(workingLaterDate.getMonth() - sign * difference2);\n let isLastMonthNotFull = compareAsc(workingLaterDate, earlierDate_) === -sign;\n if (isLastDayOfMonth(laterDate_) && difference2 === 1 && compareAsc(laterDate_, earlierDate_) === 1) {\n isLastMonthNotFull = false;\n }\n const result = sign * (difference2 - +isLastMonthNotFull);\n return result === 0 ? 0 : result;\n }\n function getRoundingMethod(method) {\n return (number) => {\n const round = method ? Math[method] : Math.trunc;\n const result = round(number);\n return result === 0 ? 0 : result;\n };\n }\n function differenceInMilliseconds(laterDate, earlierDate) {\n return +toDate(laterDate) - +toDate(earlierDate);\n }\n function differenceInSeconds(laterDate, earlierDate, options) {\n const diff = differenceInMilliseconds(laterDate, earlierDate) / 1e3;\n return getRoundingMethod(options == null ? void 0 : options.roundingMethod)(diff);\n }\n function formatDistance$3(laterDate, earlierDate, options) {\n const defaultOptions2 = getDefaultOptions();\n const locale = (options == null ? void 0 : options.locale) ?? defaultOptions2.locale ?? enUS;\n const minutesInAlmostTwoDays = 2520;\n const comparison = compareAsc(laterDate, earlierDate);\n if (isNaN(comparison)) throw new RangeError("Invalid time value");\n const localizeOptions = Object.assign({}, options, {\n addSuffix: options == null ? void 0 : options.addSuffix,\n comparison\n });\n const [laterDate_, earlierDate_] = normalizeDates(\n options == null ? void 0 : options.in,\n ...comparison > 0 ? [earlierDate, laterDate] : [laterDate, earlierDate]\n );\n const seconds = differenceInSeconds(earlierDate_, laterDate_);\n const offsetInSeconds = (getTimezoneOffsetInMilliseconds(earlierDate_) - getTimezoneOffsetInMilliseconds(laterDate_)) / 1e3;\n const minutes = Math.round((seconds - offsetInSeconds) / 60);\n let months;\n if (minutes < 2) {\n if (options == null ? void 0 : options.includeSeconds) {\n if (seconds < 5) {\n return locale.formatDistance("lessThanXSeconds", 5, localizeOptions);\n } else if (seconds < 10) {\n return locale.formatDistance("lessThanXSeconds", 10, localizeOptions);\n } else if (seconds < 20) {\n return locale.formatDistance("lessThanXSeconds", 20, localizeOptions);\n } else if (seconds < 40) {\n return locale.formatDistance("halfAMinute", 0, localizeOptions);\n } else if (seconds < 60) {\n return locale.formatDistance("lessThanXMinutes", 1, localizeOptions);\n } else {\n return locale.formatDistance("xMinutes", 1, localizeOptions);\n }\n } else {\n if (minutes === 0) {\n return locale.formatDistance("lessThanXMinutes", 1, localizeOptions);\n } else {\n return locale.formatDistance("xMinutes", minutes, localizeOptions);\n }\n }\n } else if (minutes < 45) {\n return locale.formatDistance("xMinutes", minutes, localizeOptions);\n } else if (minutes < 90) {\n return locale.formatDistance("aboutXHours", 1, localizeOptions);\n } else if (minutes < minutesInDay) {\n const hours = Math.round(minutes / 60);\n return locale.formatDistance("aboutXHours", hours, localizeOptions);\n } else if (minutes < minutesInAlmostTwoDays) {\n return locale.formatDistance("xDays", 1, localizeOptions);\n } else if (minutes < minutesInMonth) {\n const days = Math.round(minutes / minutesInDay);\n return locale.formatDistance("xDays", days, localizeOptions);\n } else if (minutes < minutesInMonth * 2) {\n months = Math.round(minutes / minutesInMonth);\n return locale.formatDistance("aboutXMonths", months, localizeOptions);\n }\n months = differenceInMonths(earlierDate_, laterDate_);\n if (months < 12) {\n const nearestMonth = Math.round(minutes / minutesInMonth);\n return locale.formatDistance("xMonths", nearestMonth, localizeOptions);\n } else {\n const monthsSinceStartOfYear = months % 12;\n const years = Math.trunc(months / 12);\n if (monthsSinceStartOfYear < 3) {\n return locale.formatDistance("aboutXYears", years, localizeOptions);\n } else if (monthsSinceStartOfYear < 9) {\n return locale.formatDistance("overXYears", years, localizeOptions);\n } else {\n return locale.formatDistance("almostXYears", years + 1, localizeOptions);\n }\n }\n }\n function formatDistanceToNow(date, options) {\n return formatDistance$3(date, constructNow(date), options);\n }\n function startOfWeek(date, options) {\n var _a, _b, _c, _d;\n const defaultOptions2 = getDefaultOptions();\n const weekStartsOn = (options == null ? void 0 : options.weekStartsOn) ?? ((_b = (_a = options == null ? void 0 : options.locale) == null ? void 0 : _a.options) == null ? void 0 : _b.weekStartsOn) ?? defaultOptions2.weekStartsOn ?? ((_d = (_c = defaultOptions2.locale) == null ? void 0 : _c.options) == null ? void 0 : _d.weekStartsOn) ?? 0;\n const _date = toDate(date, options == null ? void 0 : options.in);\n const day = _date.getDay();\n const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n _date.setDate(_date.getDate() - diff);\n _date.setHours(0, 0, 0, 0);\n return _date;\n }\n function isSameWeek(laterDate, earlierDate, options) {\n const [laterDate_, earlierDate_] = normalizeDates(\n options == null ? void 0 : options.in,\n laterDate,\n earlierDate\n );\n return +startOfWeek(laterDate_, options) === +startOfWeek(earlierDate_, options);\n }\n const formatDistanceLocale$2 = {\n lessThanXSeconds: {\n standalone: {\n one: "weniger als 1 Sekunde",\n other: "weniger als {{count}} Sekunden"\n },\n withPreposition: {\n one: "weniger als 1 Sekunde",\n other: "weniger als {{count}} Sekunden"\n }\n },\n xSeconds: {\n standalone: {\n one: "1 Sekunde",\n other: "{{count}} Sekunden"\n },\n withPreposition: {\n one: "1 Sekunde",\n other: "{{count}} Sekunden"\n }\n },\n halfAMinute: {\n standalone: "eine halbe Minute",\n withPreposition: "einer halben Minute"\n },\n lessThanXMinutes: {\n standalone: {\n one: "weniger als 1 Minute",\n other: "weniger als {{count}} Minuten"\n },\n withPreposition: {\n one: "weniger als 1 Minute",\n other: "weniger als {{count}} Minuten"\n }\n },\n xMinutes: {\n standalone: {\n one: "1 Minute",\n other: "{{count}} Minuten"\n },\n withPreposition: {\n one: "1 Minute",\n other: "{{count}} Minuten"\n }\n },\n aboutXHours: {\n standalone: {\n one: "etwa 1 Stunde",\n other: "etwa {{count}} Stunden"\n },\n withPreposition: {\n one: "etwa 1 Stunde",\n other: "etwa {{count}} Stunden"\n }\n },\n xHours: {\n standalone: {\n one: "1 Stunde",\n other: "{{count}} Stunden"\n },\n withPreposition: {\n one: "1 Stunde",\n other: "{{count}} Stunden"\n }\n },\n xDays: {\n standalone: {\n one: "1 Tag",\n other: "{{count}} Tage"\n },\n withPreposition: {\n one: "1 Tag",\n other: "{{count}} Tagen"\n }\n },\n aboutXWeeks: {\n standalone: {\n one: "etwa 1 Woche",\n other: "etwa {{count}} Wochen"\n },\n withPreposition: {\n one: "etwa 1 Woche",\n other: "etwa {{count}} Wochen"\n }\n },\n xWeeks: {\n standalone: {\n one: "1 Woche",\n other: "{{count}} Wochen"\n },\n withPreposition: {\n one: "1 Woche",\n other: "{{count}} Wochen"\n }\n },\n aboutXMonths: {\n standalone: {\n one: "etwa 1 Monat",\n other: "etwa {{count}} Monate"\n },\n withPreposition: {\n one: "etwa 1 Monat",\n other: "etwa {{count}} Monaten"\n }\n },\n xMonths: {\n standalone: {\n one: "1 Monat",\n other: "{{count}} Monate"\n },\n withPreposition: {\n one: "1 Monat",\n other: "{{count}} Monaten"\n }\n },\n aboutXYears: {\n standalone: {\n one: "etwa 1 Jahr",\n other: "etwa {{count}} Jahre"\n },\n withPreposition: {\n one: "etwa 1 Jahr",\n other: "etwa {{count}} Jahren"\n }\n },\n xYears: {\n standalone: {\n one: "1 Jahr",\n other: "{{count}} Jahre"\n },\n withPreposition: {\n one: "1 Jahr",\n other: "{{count}} Jahren"\n }\n },\n overXYears: {\n standalone: {\n one: "mehr als 1 Jahr",\n other: "mehr als {{count}} Jahre"\n },\n withPreposition: {\n one: "mehr als 1 Jahr",\n other: "mehr als {{count}} Jahren"\n }\n },\n almostXYears: {\n standalone: {\n one: "fast 1 Jahr",\n other: "fast {{count}} Jahre"\n },\n withPreposition: {\n one: "fast 1 Jahr",\n other: "fast {{count}} Jahren"\n }\n }\n };\n const formatDistance$2 = (token, count, options) => {\n let result;\n const tokenValue = (options == null ? void 0 : options.addSuffix) ? formatDistanceLocale$2[token].withPreposition : formatDistanceLocale$2[token].standalone;\n if (typeof tokenValue === "string") {\n result = tokenValue;\n } else if (count === 1) {\n result = tokenValue.one;\n } else {\n result = tokenValue.other.replace("{{count}}", String(count));\n }\n if (options == null ? void 0 : options.addSuffix) {\n if (options.comparison && options.comparison > 0) {\n return "in " + result;\n } else {\n return "vor " + result;\n }\n }\n return result;\n };\n const dateFormats$2 = {\n full: "EEEE, do MMMM y",\n // Montag, 7. Januar 2018\n long: "do MMMM y",\n // 7. Januar 2018\n medium: "do MMM y",\n // 7. Jan. 2018\n short: "dd.MM.y"\n // 07.01.2018\n };\n const timeFormats$2 = {\n full: "HH:mm:ss zzzz",\n long: "HH:mm:ss z",\n medium: "HH:mm:ss",\n short: "HH:mm"\n };\n const dateTimeFormats$2 = {\n full: "{{date}} \'um\' {{time}}",\n long: "{{date}} \'um\' {{time}}",\n medium: "{{date}} {{time}}",\n short: "{{date}} {{time}}"\n };\n const formatLong$2 = {\n date: buildFormatLongFn({\n formats: dateFormats$2,\n defaultWidth: "full"\n }),\n time: buildFormatLongFn({\n formats: timeFormats$2,\n defaultWidth: "full"\n }),\n dateTime: buildFormatLongFn({\n formats: dateTimeFormats$2,\n defaultWidth: "full"\n })\n };\n const formatRelativeLocale$2 = {\n lastWeek: "\'letzten\' eeee \'um\' p",\n yesterday: "\'gestern um\' p",\n today: "\'heute um\' p",\n tomorrow: "\'morgen um\' p",\n nextWeek: "eeee \'um\' p",\n other: "P"\n };\n const formatRelative$2 = (token, _date, _baseDate, _options2) => formatRelativeLocale$2[token];\n const eraValues$2 = {\n narrow: ["v.Chr.", "n.Chr."],\n abbreviated: ["v.Chr.", "n.Chr."],\n wide: ["vor Christus", "nach Christus"]\n };\n const quarterValues$2 = {\n narrow: ["1", "2", "3", "4"],\n abbreviated: ["Q1", "Q2", "Q3", "Q4"],\n wide: ["1. Quartal", "2. Quartal", "3. Quartal", "4. Quartal"]\n };\n const monthValues$2 = {\n narrow: ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"],\n abbreviated: [\n "Jan",\n "Feb",\n "Mär",\n "Apr",\n "Mai",\n "Jun",\n "Jul",\n "Aug",\n "Sep",\n "Okt",\n "Nov",\n "Dez"\n ],\n wide: [\n "Januar",\n "Februar",\n "März",\n "April",\n "Mai",\n "Juni",\n "Juli",\n "August",\n "September",\n "Oktober",\n "November",\n "Dezember"\n ]\n };\n const formattingMonthValues = {\n narrow: monthValues$2.narrow,\n abbreviated: [\n "Jan.",\n "Feb.",\n "März",\n "Apr.",\n "Mai",\n "Juni",\n "Juli",\n "Aug.",\n "Sep.",\n "Okt.",\n "Nov.",\n "Dez."\n ],\n wide: monthValues$2.wide\n };\n const dayValues$2 = {\n narrow: ["S", "M", "D", "M", "D", "F", "S"],\n short: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],\n abbreviated: ["So.", "Mo.", "Di.", "Mi.", "Do.", "Fr.", "Sa."],\n wide: [\n "Sonntag",\n "Montag",\n "Dienstag",\n "Mittwoch",\n "Donnerstag",\n "Freitag",\n "Samstag"\n ]\n };\n const dayPeriodValues$2 = {\n narrow: {\n am: "vm.",\n pm: "nm.",\n midnight: "Mitternacht",\n noon: "Mittag",\n morning: "Morgen",\n afternoon: "Nachm.",\n evening: "Abend",\n night: "Nacht"\n },\n abbreviated: {\n am: "vorm.",\n pm: "nachm.",\n midnight: "Mitternacht",\n noon: "Mittag",\n morning: "Morgen",\n afternoon: "Nachmittag",\n evening: "Abend",\n night: "Nacht"\n },\n wide: {\n am: "vormittags",\n pm: "nachmittags",\n midnight: "Mitternacht",\n noon: "Mittag",\n morning: "Morgen",\n afternoon: "Nachmittag",\n evening: "Abend",\n night: "Nacht"\n }\n };\n const formattingDayPeriodValues$2 = {\n narrow: {\n am: "vm.",\n pm: "nm.",\n midnight: "Mitternacht",\n noon: "Mittag",\n morning: "morgens",\n afternoon: "nachm.",\n evening: "abends",\n night: "nachts"\n },\n abbreviated: {\n am: "vorm.",\n pm: "nachm.",\n midnight: "Mitternacht",\n noon: "Mittag",\n morning: "morgens",\n afternoon: "nachmittags",\n evening: "abends",\n night: "nachts"\n },\n wide: {\n am: "vormittags",\n pm: "nachmittags",\n midnight: "Mitternacht",\n noon: "Mittag",\n morning: "morgens",\n afternoon: "nachmittags",\n evening: "abends",\n night: "nachts"\n }\n };\n const ordinalNumber$2 = (dirtyNumber) => {\n const number = Number(dirtyNumber);\n return number + ".";\n };\n const localize$2 = {\n ordinalNumber: ordinalNumber$2,\n era: buildLocalizeFn({\n values: eraValues$2,\n defaultWidth: "wide"\n }),\n quarter: buildLocalizeFn({\n values: quarterValues$2,\n defaultWidth: "wide",\n argumentCallback: (quarter) => quarter - 1\n }),\n month: buildLocalizeFn({\n values: monthValues$2,\n formattingValues: formattingMonthValues,\n defaultWidth: "wide"\n }),\n day: buildLocalizeFn({\n values: dayValues$2,\n defaultWidth: "wide"\n }),\n dayPeriod: buildLocalizeFn({\n values: dayPeriodValues$2,\n defaultWidth: "wide",\n formattingValues: formattingDayPeriodValues$2,\n defaultFormattingWidth: "wide"\n })\n };\n const matchOrdinalNumberPattern$2 = /^(\\d+)(\\.)?/i;\n const parseOrdinalNumberPattern$2 = /\\d+/i;\n const matchEraPatterns$2 = {\n narrow: /^(v\\.? ?Chr\\.?|n\\.? ?Chr\\.?)/i,\n abbreviated: /^(v\\.? ?Chr\\.?|n\\.? ?Chr\\.?)/i,\n wide: /^(vor Christus|vor unserer Zeitrechnung|nach Christus|unserer Zeitrechnung)/i\n };\n const parseEraPatterns$2 = {\n any: [/^v/i, /^n/i]\n };\n const matchQuarterPatterns$2 = {\n narrow: /^[1234]/i,\n abbreviated: /^q[1234]/i,\n wide: /^[1234](\\.)? Quartal/i\n };\n const parseQuarterPatterns$2 = {\n any: [/1/i, /2/i, /3/i, /4/i]\n };\n const matchMonthPatterns$2 = {\n narrow: /^[jfmasond]/i,\n abbreviated: /^(j[aä]n|feb|mär[z]?|apr|mai|jun[i]?|jul[i]?|aug|sep|okt|nov|dez)\\.?/i,\n wide: /^(januar|februar|märz|april|mai|juni|juli|august|september|oktober|november|dezember)/i\n };\n const parseMonthPatterns$2 = {\n narrow: [\n /^j/i,\n /^f/i,\n /^m/i,\n /^a/i,\n /^m/i,\n /^j/i,\n /^j/i,\n /^a/i,\n /^s/i,\n /^o/i,\n /^n/i,\n /^d/i\n ],\n any: [\n /^j[aä]/i,\n /^f/i,\n /^mär/i,\n /^ap/i,\n /^mai/i,\n /^jun/i,\n /^jul/i,\n /^au/i,\n /^s/i,\n /^o/i,\n /^n/i,\n /^d/i\n ]\n };\n const matchDayPatterns$2 = {\n narrow: /^[smdmf]/i,\n short: /^(so|mo|di|mi|do|fr|sa)/i,\n abbreviated: /^(son?|mon?|die?|mit?|don?|fre?|sam?)\\.?/i,\n wide: /^(sonntag|montag|dienstag|mittwoch|donnerstag|freitag|samstag)/i\n };\n const parseDayPatterns$2 = {\n any: [/^so/i, /^mo/i, /^di/i, /^mi/i, /^do/i, /^f/i, /^sa/i]\n };\n const matchDayPeriodPatterns$2 = {\n narrow: /^(vm\\.?|nm\\.?|Mitternacht|Mittag|morgens|nachm\\.?|abends|nachts)/i,\n abbreviated: /^(vorm\\.?|nachm\\.?|Mitternacht|Mittag|morgens|nachm\\.?|abends|nachts)/i,\n wide: /^(vormittags|nachmittags|Mitternacht|Mittag|morgens|nachmittags|abends|nachts)/i\n };\n const parseDayPeriodPatterns$2 = {\n any: {\n am: /^v/i,\n pm: /^n/i,\n midnight: /^Mitte/i,\n noon: /^Mitta/i,\n morning: /morgens/i,\n afternoon: /nachmittags/i,\n // will never be matched. Afternoon is matched by `pm`\n evening: /abends/i,\n night: /nachts/i\n // will never be matched. Night is matched by `pm`\n }\n };\n const match$2 = {\n ordinalNumber: buildMatchPatternFn({\n matchPattern: matchOrdinalNumberPattern$2,\n parsePattern: parseOrdinalNumberPattern$2,\n valueCallback: (value) => parseInt(value)\n }),\n era: buildMatchFn({\n matchPatterns: matchEraPatterns$2,\n defaultMatchWidth: "wide",\n parsePatterns: parseEraPatterns$2,\n defaultParseWidth: "any"\n }),\n quarter: buildMatchFn({\n matchPatterns: matchQuarterPatterns$2,\n defaultMatchWidth: "wide",\n parsePatterns: parseQuarterPatterns$2,\n defaultParseWidth: "any",\n valueCallback: (index) => index + 1\n }),\n month: buildMatchFn({\n matchPatterns: matchMonthPatterns$2,\n defaultMatchWidth: "wide",\n parsePatterns: parseMonthPatterns$2,\n defaultParseWidth: "any"\n }),\n day: buildMatchFn({\n matchPatterns: matchDayPatterns$2,\n defaultMatchWidth: "wide",\n parsePatterns: parseDayPatterns$2,\n defaultParseWidth: "any"\n }),\n dayPeriod: buildMatchFn({\n matchPatterns: matchDayPeriodPatterns$2,\n defaultMatchWidth: "wide",\n parsePatterns: parseDayPeriodPatterns$2,\n defaultParseWidth: "any"\n })\n };\n const de = {\n code: "de",\n formatDistance: formatDistance$2,\n formatLong: formatLong$2,\n formatRelative: formatRelative$2,\n localize: localize$2,\n match: match$2,\n options: {\n weekStartsOn: 1,\n firstWeekContainsDate: 4\n }\n };\n const formatDistanceLocale$1 = {\n lessThanXSeconds: {\n one: "פחות משנייה",\n two: "פחות משתי שניות",\n other: "פחות מ־{{count}} שניות"\n },\n xSeconds: {\n one: "שנייה",\n two: "שתי שניות",\n other: "{{count}} שניות"\n },\n halfAMinute: "חצי דקה",\n lessThanXMinutes: {\n one: "פחות מדקה",\n two: "פחות משתי דקות",\n other: "פחות מ־{{count}} דקות"\n },\n xMinutes: {\n one: "דקה",\n two: "שתי דקות",\n other: "{{count}} דקות"\n },\n aboutXHours: {\n one: "כשעה",\n two: "כשעתיים",\n other: "כ־{{count}} שעות"\n },\n xHours: {\n one: "שעה",\n two: "שעתיים",\n other: "{{count}} שעות"\n },\n xDays: {\n one: "יום",\n two: "יומיים",\n other: "{{count}} ימים"\n },\n aboutXWeeks: {\n one: "כשבוע",\n two: "כשבועיים",\n other: "כ־{{count}} שבועות"\n },\n xWeeks: {\n one: "שבוע",\n two: "שבועיים",\n other: "{{count}} שבועות"\n },\n aboutXMonths: {\n one: "כחודש",\n two: "כחודשיים",\n other: "כ־{{count}} חודשים"\n },\n xMonths: {\n one: "חודש",\n two: "חודשיים",\n other: "{{count}} חודשים"\n },\n aboutXYears: {\n one: "כשנה",\n two: "כשנתיים",\n other: "כ־{{count}} שנים"\n },\n xYears: {\n one: "שנה",\n two: "שנתיים",\n other: "{{count}} שנים"\n },\n overXYears: {\n one: "יותר משנה",\n two: "יותר משנתיים",\n other: "יותר מ־{{count}} שנים"\n },\n almostXYears: {\n one: "כמעט שנה",\n two: "כמעט שנתיים",\n other: "כמעט {{count}} שנים"\n }\n };\n const formatDistance$1 = (token, count, options) => {\n if (token === "xDays" && (options == null ? void 0 : options.addSuffix) && count <= 2) {\n if (options.comparison && options.comparison > 0) {\n return count === 1 ? "מחר" : "מחרתיים";\n }\n return count === 1 ? "אתמול" : "שלשום";\n }\n let result;\n const tokenValue = formatDistanceLocale$1[token];\n if (typeof tokenValue === "string") {\n result = tokenValue;\n } else if (count === 1) {\n result = tokenValue.one;\n } else if (count === 2) {\n result = tokenValue.two;\n } else {\n result = tokenValue.other.replace("{{count}}", String(count));\n }\n if (options == null ? void 0 : options.addSuffix) {\n if (options.comparison && options.comparison > 0) {\n return "בעוד " + result;\n } else {\n return "לפני " + result;\n }\n }\n return result;\n };\n const dateFormats$1 = {\n full: "EEEE, d בMMMM y",\n long: "d בMMMM y",\n medium: "d בMMM y",\n short: "d.M.y"\n };\n const timeFormats$1 = {\n full: "H:mm:ss zzzz",\n long: "H:mm:ss z",\n medium: "H:mm:ss",\n short: "H:mm"\n };\n const dateTimeFormats$1 = {\n full: "{{date}} \'בשעה\' {{time}}",\n long: "{{date}} \'בשעה\' {{time}}",\n medium: "{{date}}, {{time}}",\n short: "{{date}}, {{time}}"\n };\n const formatLong$1 = {\n date: buildFormatLongFn({\n formats: dateFormats$1,\n defaultWidth: "full"\n }),\n time: buildFormatLongFn({\n formats: timeFormats$1,\n defaultWidth: "full"\n }),\n dateTime: buildFormatLongFn({\n formats: dateTimeFormats$1,\n defaultWidth: "full"\n })\n };\n const formatRelativeLocale$1 = {\n lastWeek: "eeee \'שעבר בשעה\' p",\n yesterday: "\'אתמול בשעה\' p",\n today: "\'היום בשעה\' p",\n tomorrow: "\'מחר בשעה\' p",\n nextWeek: "eeee \'בשעה\' p",\n other: "P"\n };\n const formatRelative$1 = (token, _date, _baseDate, _options2) => formatRelativeLocale$1[token];\n const eraValues$1 = {\n narrow: ["לפנה״ס", "לספירה"],\n abbreviated: ["לפנה״ס", "לספירה"],\n wide: ["לפני הספירה", "לספירה"]\n };\n const quarterValues$1 = {\n narrow: ["1", "2", "3", "4"],\n abbreviated: ["Q1", "Q2", "Q3", "Q4"],\n wide: ["רבעון 1", "רבעון 2", "רבעון 3", "רבעון 4"]\n };\n const monthValues$1 = {\n narrow: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],\n abbreviated: [\n "ינו׳",\n "פבר׳",\n "מרץ",\n "אפר׳",\n "מאי",\n "יוני",\n "יולי",\n "אוג׳",\n "ספט׳",\n "אוק׳",\n "נוב׳",\n "דצמ׳"\n ],\n wide: [\n "ינואר",\n "פברואר",\n "מרץ",\n "אפריל",\n "מאי",\n "יוני",\n "יולי",\n "אוגוסט",\n "ספטמבר",\n "אוקטובר",\n "נובמבר",\n "דצמבר"\n ]\n };\n const dayValues$1 = {\n narrow: ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"],\n short: ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"],\n abbreviated: [\n "יום א׳",\n "יום ב׳",\n "יום ג׳",\n "יום ד׳",\n "יום ה׳",\n "יום ו׳",\n "שבת"\n ],\n wide: [\n "יום ראשון",\n "יום שני",\n "יום שלישי",\n "יום רביעי",\n "יום חמישי",\n "יום שישי",\n "יום שבת"\n ]\n };\n const dayPeriodValues$1 = {\n narrow: {\n am: "לפנה״צ",\n pm: "אחה״צ",\n midnight: "חצות",\n noon: "צהריים",\n morning: "בוקר",\n afternoon: "אחר הצהריים",\n evening: "ערב",\n night: "לילה"\n },\n abbreviated: {\n am: "לפנה״צ",\n pm: "אחה״צ",\n midnight: "חצות",\n noon: "צהריים",\n morning: "בוקר",\n afternoon: "אחר הצהריים",\n evening: "ערב",\n night: "לילה"\n },\n wide: {\n am: "לפנה״צ",\n pm: "אחה״צ",\n midnight: "חצות",\n noon: "צהריים",\n morning: "בוקר",\n afternoon: "אחר הצהריים",\n evening: "ערב",\n night: "לילה"\n }\n };\n const formattingDayPeriodValues$1 = {\n narrow: {\n am: "לפנה״צ",\n pm: "אחה״צ",\n midnight: "חצות",\n noon: "צהריים",\n morning: "בבוקר",\n afternoon: "בצהריים",\n evening: "בערב",\n night: "בלילה"\n },\n abbreviated: {\n am: "לפנה״צ",\n pm: "אחה״צ",\n midnight: "חצות",\n noon: "צהריים",\n morning: "בבוקר",\n afternoon: "אחר הצהריים",\n evening: "בערב",\n night: "בלילה"\n },\n wide: {\n am: "לפנה״צ",\n pm: "אחה״צ",\n midnight: "חצות",\n noon: "צהריים",\n morning: "בבוקר",\n afternoon: "אחר הצהריים",\n evening: "בערב",\n night: "בלילה"\n }\n };\n const ordinalNumber$1 = (dirtyNumber, options) => {\n const number = Number(dirtyNumber);\n if (number <= 0 || number > 10) return String(number);\n const unit = String(options == null ? void 0 : options.unit);\n const isFemale = ["year", "hour", "minute", "second"].indexOf(unit) >= 0;\n const male = [\n "ראשון",\n "שני",\n "שלישי",\n "רביעי",\n "חמישי",\n "שישי",\n "שביעי",\n "שמיני",\n "תשיעי",\n "עשירי"\n ];\n const female = [\n "ראשונה",\n "שנייה",\n "שלישית",\n "רביעית",\n "חמישית",\n "שישית",\n "שביעית",\n "שמינית",\n "תשיעית",\n "עשירית"\n ];\n const index = number - 1;\n return isFemale ? female[index] : male[index];\n };\n const localize$1 = {\n ordinalNumber: ordinalNumber$1,\n era: buildLocalizeFn({\n values: eraValues$1,\n defaultWidth: "wide"\n }),\n quarter: buildLocalizeFn({\n values: quarterValues$1,\n defaultWidth: "wide",\n argumentCallback: (quarter) => quarter - 1\n }),\n month: buildLocalizeFn({\n values: monthValues$1,\n defaultWidth: "wide"\n }),\n day: buildLocalizeFn({\n values: dayValues$1,\n defaultWidth: "wide"\n }),\n dayPeriod: buildLocalizeFn({\n values: dayPeriodValues$1,\n defaultWidth: "wide",\n formattingValues: formattingDayPeriodValues$1,\n defaultFormattingWidth: "wide"\n })\n };\n const matchOrdinalNumberPattern$1 = /^(\\d+|(ראשון|שני|שלישי|רביעי|חמישי|שישי|שביעי|שמיני|תשיעי|עשירי|ראשונה|שנייה|שלישית|רביעית|חמישית|שישית|שביעית|שמינית|תשיעית|עשירית))/i;\n const parseOrdinalNumberPattern$1 = /^(\\d+|רא|שנ|של|רב|ח|שי|שב|שמ|ת|ע)/i;\n const matchEraPatterns$1 = {\n narrow: /^ל(ספירה|פנה״ס)/i,\n abbreviated: /^ל(ספירה|פנה״ס)/i,\n wide: /^ל(פני ה)?ספירה/i\n };\n const parseEraPatterns$1 = {\n any: [/^לפ/i, /^לס/i]\n };\n const matchQuarterPatterns$1 = {\n narrow: /^[1234]/i,\n abbreviated: /^q[1234]/i,\n wide: /^רבעון [1234]/i\n };\n const parseQuarterPatterns$1 = {\n any: [/1/i, /2/i, /3/i, /4/i]\n };\n const matchMonthPatterns$1 = {\n narrow: /^\\d+/i,\n abbreviated: /^(ינו|פבר|מרץ|אפר|מאי|יוני|יולי|אוג|ספט|אוק|נוב|דצמ)׳?/i,\n wide: /^(ינואר|פברואר|מרץ|אפריל|מאי|יוני|יולי|אוגוסט|ספטמבר|אוקטובר|נובמבר|דצמבר)/i\n };\n const parseMonthPatterns$1 = {\n narrow: [\n /^1$/i,\n /^2/i,\n /^3/i,\n /^4/i,\n /^5/i,\n /^6/i,\n /^7/i,\n /^8/i,\n /^9/i,\n /^10/i,\n /^11/i,\n /^12/i\n ],\n any: [\n /^ינ/i,\n /^פ/i,\n /^מר/i,\n /^אפ/i,\n /^מא/i,\n /^יונ/i,\n /^יול/i,\n /^אוג/i,\n /^ס/i,\n /^אוק/i,\n /^נ/i,\n /^ד/i\n ]\n };\n const matchDayPatterns$1 = {\n narrow: /^[אבגדהוש]׳/i,\n short: /^[אבגדהוש]׳/i,\n abbreviated: /^(שבת|יום (א|ב|ג|ד|ה|ו)׳)/i,\n wide: /^יום (ראשון|שני|שלישי|רביעי|חמישי|שישי|שבת)/i\n };\n const parseDayPatterns$1 = {\n abbreviated: [/א׳$/i, /ב׳$/i, /ג׳$/i, /ד׳$/i, /ה׳$/i, /ו׳$/i, /^ש/i],\n wide: [/ן$/i, /ני$/i, /לישי$/i, /עי$/i, /מישי$/i, /שישי$/i, /ת$/i],\n any: [/^א/i, /^ב/i, /^ג/i, /^ד/i, /^ה/i, /^ו/i, /^ש/i]\n };\n const matchDayPeriodPatterns$1 = {\n any: /^(אחר ה|ב)?(חצות|צהריים|בוקר|ערב|לילה|אחה״צ|לפנה״צ)/i\n };\n const parseDayPeriodPatterns$1 = {\n any: {\n am: /^לפ/i,\n pm: /^אחה/i,\n midnight: /^ח/i,\n noon: /^צ/i,\n morning: /בוקר/i,\n afternoon: /בצ|אחר/i,\n evening: /ערב/i,\n night: /לילה/i\n }\n };\n const ordinalName = ["רא", "שנ", "של", "רב", "ח", "שי", "שב", "שמ", "ת", "ע"];\n const match$1 = {\n ordinalNumber: buildMatchPatternFn({\n matchPattern: matchOrdinalNumberPattern$1,\n parsePattern: parseOrdinalNumberPattern$1,\n valueCallback: (value) => {\n const number = parseInt(value, 10);\n return isNaN(number) ? ordinalName.indexOf(value) + 1 : number;\n }\n }),\n era: buildMatchFn({\n matchPatterns: matchEraPatterns$1,\n defaultMatchWidth: "wide",\n parsePatterns: parseEraPatterns$1,\n defaultParseWidth: "any"\n }),\n quarter: buildMatchFn({\n matchPatterns: matchQuarterPatterns$1,\n defaultMatchWidth: "wide",\n parsePatterns: parseQuarterPatterns$1,\n defaultParseWidth: "any",\n valueCallback: (index) => index + 1\n }),\n month: buildMatchFn({\n matchPatterns: matchMonthPatterns$1,\n defaultMatchWidth: "wide",\n parsePatterns: parseMonthPatterns$1,\n defaultParseWidth: "any"\n }),\n day: buildMatchFn({\n matchPatterns: matchDayPatterns$1,\n defaultMatchWidth: "wide",\n parsePatterns: parseDayPatterns$1,\n defaultParseWidth: "any"\n }),\n dayPeriod: buildMatchFn({\n matchPatterns: matchDayPeriodPatterns$1,\n defaultMatchWidth: "any",\n parsePatterns: parseDayPeriodPatterns$1,\n defaultParseWidth: "any"\n })\n };\n const he = {\n code: "he",\n formatDistance: formatDistance$1,\n formatLong: formatLong$1,\n formatRelative: formatRelative$1,\n localize: localize$1,\n match: match$1,\n options: {\n weekStartsOn: 0,\n firstWeekContainsDate: 1\n }\n };\n const formatDistanceLocale = {\n lessThanXSeconds: {\n one: "不到 1 秒",\n other: "不到 {{count}} 秒"\n },\n xSeconds: {\n one: "1 秒",\n other: "{{count}} 秒"\n },\n halfAMinute: "半分钟",\n lessThanXMinutes: {\n one: "不到 1 分钟",\n other: "不到 {{count}} 分钟"\n },\n xMinutes: {\n one: "1 分钟",\n other: "{{count}} 分钟"\n },\n xHours: {\n one: "1 小时",\n other: "{{count}} 小时"\n },\n aboutXHours: {\n one: "大约 1 小时",\n other: "大约 {{count}} 小时"\n },\n xDays: {\n one: "1 天",\n other: "{{count}} 天"\n },\n aboutXWeeks: {\n one: "大约 1 个星期",\n other: "大约 {{count}} 个星期"\n },\n xWeeks: {\n one: "1 个星期",\n other: "{{count}} 个星期"\n },\n aboutXMonths: {\n one: "大约 1 个月",\n other: "大约 {{count}} 个月"\n },\n xMonths: {\n one: "1 个月",\n other: "{{count}} 个月"\n },\n aboutXYears: {\n one: "大约 1 年",\n other: "大约 {{count}} 年"\n },\n xYears: {\n one: "1 年",\n other: "{{count}} 年"\n },\n overXYears: {\n one: "超过 1 年",\n other: "超过 {{count}} 年"\n },\n almostXYears: {\n one: "将近 1 年",\n other: "将近 {{count}} 年"\n }\n };\n const formatDistance = (token, count, options) => {\n let result;\n const tokenValue = formatDistanceLocale[token];\n if (typeof tokenValue === "string") {\n result = tokenValue;\n } else if (count === 1) {\n result = tokenValue.one;\n } else {\n result = tokenValue.other.replace("{{count}}", String(count));\n }\n if (options == null ? void 0 : options.addSuffix) {\n if (options.comparison && options.comparison > 0) {\n return result + "内";\n } else {\n return result + "前";\n }\n }\n return result;\n };\n const dateFormats = {\n full: "y\'年\'M\'月\'d\'日\' EEEE",\n long: "y\'年\'M\'月\'d\'日\'",\n medium: "yyyy-MM-dd",\n short: "yy-MM-dd"\n };\n const timeFormats = {\n full: "zzzz a h:mm:ss",\n long: "z a h:mm:ss",\n medium: "a h:mm:ss",\n short: "a h:mm"\n };\n const dateTimeFormats = {\n full: "{{date}} {{time}}",\n long: "{{date}} {{time}}",\n medium: "{{date}} {{time}}",\n short: "{{date}} {{time}}"\n };\n const formatLong = {\n date: buildFormatLongFn({\n formats: dateFormats,\n defaultWidth: "full"\n }),\n time: buildFormatLongFn({\n formats: timeFormats,\n defaultWidth: "full"\n }),\n dateTime: buildFormatLongFn({\n formats: dateTimeFormats,\n defaultWidth: "full"\n })\n };\n function checkWeek(date, baseDate, options) {\n const baseFormat = "eeee p";\n if (isSameWeek(date, baseDate, options)) {\n return baseFormat;\n } else if (date.getTime() > baseDate.getTime()) {\n return "\'下个\'" + baseFormat;\n }\n return "\'上个\'" + baseFormat;\n }\n const formatRelativeLocale = {\n lastWeek: checkWeek,\n // days before yesterday, maybe in this week or last week\n yesterday: "\'昨天\' p",\n today: "\'今天\' p",\n tomorrow: "\'明天\' p",\n nextWeek: checkWeek,\n // days after tomorrow, maybe in this week or next week\n other: "PP p"\n };\n const formatRelative = (token, date, baseDate, options) => {\n const format = formatRelativeLocale[token];\n if (typeof format === "function") {\n return format(date, baseDate, options);\n }\n return format;\n };\n const eraValues = {\n narrow: ["前", "公元"],\n abbreviated: ["前", "公元"],\n wide: ["公元前", "公元"]\n };\n const quarterValues = {\n narrow: ["1", "2", "3", "4"],\n abbreviated: ["第一季", "第二季", "第三季", "第四季"],\n wide: ["第一季度", "第二季度", "第三季度", "第四季度"]\n };\n const monthValues = {\n narrow: [\n "一",\n "二",\n "三",\n "四",\n "五",\n "六",\n "七",\n "八",\n "九",\n "十",\n "十一",\n "十二"\n ],\n abbreviated: [\n "1月",\n "2月",\n "3月",\n "4月",\n "5月",\n "6月",\n "7月",\n "8月",\n "9月",\n "10月",\n "11月",\n "12月"\n ],\n wide: [\n "一月",\n "二月",\n "三月",\n "四月",\n "五月",\n "六月",\n "七月",\n "八月",\n "九月",\n "十月",\n "十一月",\n "十二月"\n ]\n };\n const dayValues = {\n narrow: ["日", "一", "二", "三", "四", "五", "六"],\n short: ["日", "一", "二", "三", "四", "五", "六"],\n abbreviated: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],\n wide: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]\n };\n const dayPeriodValues = {\n narrow: {\n am: "上",\n pm: "下",\n midnight: "凌晨",\n noon: "午",\n morning: "早",\n afternoon: "下午",\n evening: "晚",\n night: "夜"\n },\n abbreviated: {\n am: "上午",\n pm: "下午",\n midnight: "凌晨",\n noon: "中午",\n morning: "早晨",\n afternoon: "中午",\n evening: "晚上",\n night: "夜间"\n },\n wide: {\n am: "上午",\n pm: "下午",\n midnight: "凌晨",\n noon: "中午",\n morning: "早晨",\n afternoon: "中午",\n evening: "晚上",\n night: "夜间"\n }\n };\n const formattingDayPeriodValues = {\n narrow: {\n am: "上",\n pm: "下",\n midnight: "凌晨",\n noon: "午",\n morning: "早",\n afternoon: "下午",\n evening: "晚",\n night: "夜"\n },\n abbreviated: {\n am: "上午",\n pm: "下午",\n midnight: "凌晨",\n noon: "中午",\n morning: "早晨",\n afternoon: "中午",\n evening: "晚上",\n night: "夜间"\n },\n wide: {\n am: "上午",\n pm: "下午",\n midnight: "凌晨",\n noon: "中午",\n morning: "早晨",\n afternoon: "中午",\n evening: "晚上",\n night: "夜间"\n }\n };\n const ordinalNumber = (dirtyNumber, options) => {\n const number = Number(dirtyNumber);\n switch (options == null ? void 0 : options.unit) {\n case "date":\n return number.toString() + "日";\n case "hour":\n return number.toString() + "时";\n case "minute":\n return number.toString() + "分";\n case "second":\n return number.toString() + "秒";\n default:\n return "第 " + number.toString();\n }\n };\n const localize = {\n ordinalNumber,\n era: buildLocalizeFn({\n values: eraValues,\n defaultWidth: "wide"\n }),\n quarter: buildLocalizeFn({\n values: quarterValues,\n defaultWidth: "wide",\n argumentCallback: (quarter) => quarter - 1\n }),\n month: buildLocalizeFn({\n values: monthValues,\n defaultWidth: "wide"\n }),\n day: buildLocalizeFn({\n values: dayValues,\n defaultWidth: "wide"\n }),\n dayPeriod: buildLocalizeFn({\n values: dayPeriodValues,\n defaultWidth: "wide",\n formattingValues: formattingDayPeriodValues,\n defaultFormattingWidth: "wide"\n })\n };\n const matchOrdinalNumberPattern = /^(第\\s*)?\\d+(日|时|分|秒)?/i;\n const parseOrdinalNumberPattern = /\\d+/i;\n const matchEraPatterns = {\n narrow: /^(前)/i,\n abbreviated: /^(前)/i,\n wide: /^(公元前|公元)/i\n };\n const parseEraPatterns = {\n any: [/^(前)/i, /^(公元)/i]\n };\n const matchQuarterPatterns = {\n narrow: /^[1234]/i,\n abbreviated: /^第[一二三四]刻/i,\n wide: /^第[一二三四]刻钟/i\n };\n const parseQuarterPatterns = {\n any: [/(1|一)/i, /(2|二)/i, /(3|三)/i, /(4|四)/i]\n };\n const matchMonthPatterns = {\n narrow: /^(一|二|三|四|五|六|七|八|九|十[二一])/i,\n abbreviated: /^(一|二|三|四|五|六|七|八|九|十[二一]|\\d|1[12])月/i,\n wide: /^(一|二|三|四|五|六|七|八|九|十[二一])月/i\n };\n const parseMonthPatterns = {\n narrow: [\n /^一/i,\n /^二/i,\n /^三/i,\n /^四/i,\n /^五/i,\n /^六/i,\n /^七/i,\n /^八/i,\n /^九/i,\n /^十(?!(一|二))/i,\n /^十一/i,\n /^十二/i\n ],\n any: [\n /^一|1/i,\n /^二|2/i,\n /^三|3/i,\n /^四|4/i,\n /^五|5/i,\n /^六|6/i,\n /^七|7/i,\n /^八|8/i,\n /^九|9/i,\n /^十(?!(一|二))|10/i,\n /^十一|11/i,\n /^十二|12/i\n ]\n };\n const matchDayPatterns = {\n narrow: /^[一二三四五六日]/i,\n short: /^[一二三四五六日]/i,\n abbreviated: /^周[一二三四五六日]/i,\n wide: /^星期[一二三四五六日]/i\n };\n const parseDayPatterns = {\n any: [/日/i, /一/i, /二/i, /三/i, /四/i, /五/i, /六/i]\n };\n const matchDayPeriodPatterns = {\n any: /^(上午?|下午?|午夜|[中正]午|早上?|下午|晚上?|凌晨|)/i\n };\n const parseDayPeriodPatterns = {\n any: {\n am: /^上午?/i,\n pm: /^下午?/i,\n midnight: /^午夜/i,\n noon: /^[中正]午/i,\n morning: /^早上/i,\n afternoon: /^下午/i,\n evening: /^晚上?/i,\n night: /^凌晨/i\n }\n };\n const match = {\n ordinalNumber: buildMatchPatternFn({\n matchPattern: matchOrdinalNumberPattern,\n parsePattern: parseOrdinalNumberPattern,\n valueCallback: (value) => parseInt(value, 10)\n }),\n era: buildMatchFn({\n matchPatterns: matchEraPatterns,\n defaultMatchWidth: "wide",\n parsePatterns: parseEraPatterns,\n defaultParseWidth: "any"\n }),\n quarter: buildMatchFn({\n matchPatterns: matchQuarterPatterns,\n defaultMatchWidth: "wide",\n parsePatterns: parseQuarterPatterns,\n defaultParseWidth: "any",\n valueCallback: (index) => index + 1\n }),\n month: buildMatchFn({\n matchPatterns: matchMonthPatterns,\n defaultMatchWidth: "wide",\n parsePatterns: parseMonthPatterns,\n defaultParseWidth: "any"\n }),\n day: buildMatchFn({\n matchPatterns: matchDayPatterns,\n defaultMatchWidth: "wide",\n parsePatterns: parseDayPatterns,\n defaultParseWidth: "any"\n }),\n dayPeriod: buildMatchFn({\n matchPatterns: matchDayPeriodPatterns,\n defaultMatchWidth: "any",\n parsePatterns: parseDayPeriodPatterns,\n defaultParseWidth: "any"\n })\n };\n const zhCN = {\n code: "zh-CN",\n formatDistance,\n formatLong,\n formatRelative,\n localize,\n match,\n options: {\n weekStartsOn: 1,\n firstWeekContainsDate: 4\n }\n };\n class SavegameLoader {\n constructor(game2) {\n __publicField(this, "_game");\n this._game = game2;\n }\n /**\n * Conveniently wraps the savegame loading process in an async construct.\n *\n * @param data The savegame data to load. We accept `null` here for convenience\n * when dealing with `import`ed save game data.\n * @returns Nothing\n */\n load(data) {\n return new Promise((resolve, reject) => {\n if (data === null) {\n resolve();\n return;\n }\n this._game.saveImportDropboxText(data, (error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n loadRaw(data) {\n const compressed = this._game.compressLZData(JSON.stringify(data));\n return this.load(compressed);\n }\n }\n class ToolbarListItem extends ListItem {\n constructor(parent, options) {\n super(parent, options);\n this.element.addClass(styles$7.toolbar);\n }\n toString() {\n return `[${ToolbarListItem.name}#${this.componentId}]`;\n }\n addChild(child) {\n return super.addChild(child);\n }\n }\n class StateManagementUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${StateManagementUi.name}`));\n const label2 = parent.host.engine.i18n("state.title");\n super(\n parent,\n settings,\n new LabelListItem(parent, label2, {\n classes: [stylesSettingListItem.checked, stylesSettingListItem.setting],\n icon: Icons.State\n }).addChildrenHead([\n new Container(parent, {\n classes: [stylesLabelListItem.fillSpace]\n })\n ]),\n {\n onRefresh: () => {\n this._refreshGameList();\n this._refreshStateList();\n }\n }\n );\n __publicField(this, "games", new Array());\n /**\n * The states persisted to local storage. They use Unique<T> so that when we\n * provide a state to the engine to load or get a state from the engine to\n * save, we are not accidentally sharing a reference to a live object.\n */\n __publicField(this, "states", new Array());\n __publicField(this, "gameList");\n __publicField(this, "stateList");\n __publicField(this, "locale");\n this.gameList = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n });\n this.stateList = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n });\n this.locale = locale.selected === "zh-CN" ? zhCN : locale.selected === "he-IL" ? he : locale.selected === "de-DE" ? de : enUS;\n this.addChildContent(\n new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([\n new SettingListItem(this, this.setting.noConfirm, this.host.engine.i18n("state.noConfirm")),\n new ListItem(this).addChild(new Delimiter(this)),\n new HeaderListItem(this, this.host.engine.i18n("state.local")),\n new ToolbarListItem(this).addChildren([\n new Button(this, this.host.engine.i18n("state.import"), Icons.Import, {\n onClick: () => {\n this.import();\n },\n title: this.host.engine.i18n("state.importTitle")\n })\n ]),\n new ListItem(this).addChild(new Delimiter(this)),\n new HeaderListItem(this, this.host.engine.i18n("state.localStates")),\n new ToolbarListItem(this).addChildren([\n new Button(this, this.host.engine.i18n("state.store"), Icons.SaveAs, {\n onClick: () => {\n this.storeState();\n },\n title: this.host.engine.i18n("state.storeState")\n }),\n new Button(this, this.host.engine.i18n("copy"), Icons.Copy, {\n onClick: () => {\n this.copyState().catch(redirectErrorsToConsole(console));\n this.host.engine.imessage("state.copied.stateCurrent");\n },\n title: this.host.engine.i18n("state.copy.stateCurrent")\n }),\n new Button(this, this.host.engine.i18n("state.new"), Icons.Draft, {\n onClick: () => {\n this.storeStateFactoryDefaults();\n this.host.engine.imessage("state.stored.state");\n },\n title: this.host.engine.i18n("state.storeFactory")\n }),\n new Button(this, this.host.engine.i18n("state.exportAll"), Icons.Sync, {\n onClick: () => {\n this.exportStateAll();\n },\n title: this.host.engine.i18n("state.exportAllTitle")\n })\n ]),\n new ListItem(this).addChild(this.stateList),\n new ListItem(this).addChild(new Delimiter(this)),\n new HeaderListItem(this, this.host.engine.i18n("state.localGames")),\n new ToolbarListItem(this).addChildren([\n new Button(this, this.host.engine.i18n("state.store"), Icons.SaveAs, {\n onClick: () => {\n this.storeGame();\n this.host.engine.imessage("state.stored.game");\n },\n title: this.host.engine.i18n("state.storeGame")\n }),\n new Button(this, this.host.engine.i18n("copy"), Icons.Copy, {\n onClick: () => {\n this.copyGame().catch(redirectErrorsToConsole(console));\n this.host.engine.imessage("state.copied.gameCurrent");\n },\n title: this.host.engine.i18n("state.copy.gameCurrent")\n })\n ]),\n new ListItem(this).addChild(this.gameList),\n new SettingListItem(this, this.setting.compress, this.host.engine.i18n("state.compress"))\n ])\n );\n this._loadGames();\n this._loadStates();\n }\n _loadGames() {\n let index = 0;\n let game2 = localStorage.getItem(`ks.game.${index}`);\n this.games.splice(0);\n try {\n while (!isNil(game2)) {\n const gameObject = JSON.parse(game2);\n this.games.push(new Unique(gameObject));\n game2 = localStorage.getItem(`ks.game.${++index}`);\n }\n } catch (error) {\n console.error(...cl(error));\n }\n }\n _storeGames() {\n let index = 0;\n let game2 = localStorage.getItem(`ks.game.${index}`);\n while (!isNil(game2)) {\n localStorage.removeItem(`ks.game.${index}`);\n game2 = localStorage.getItem(`ks.game.${++index}`);\n }\n index = 0;\n for (const game22 of this.games) {\n localStorage.setItem(`ks.game.${index++}`, JSON.stringify(game22));\n }\n }\n _loadStates() {\n let stateIndex = 0;\n let state = localStorage.getItem(`ks.state.${stateIndex}`);\n this.states.splice(0);\n try {\n while (!isNil(state)) {\n const stateObject = JSON.parse(state);\n KittenScientists.unknownAsEngineStateOrThrow(stateObject.state);\n this.states.push(new Unique(stateObject));\n state = localStorage.getItem(`ks.state.${++stateIndex}`);\n }\n } catch (error) {\n console.error(...cl(error));\n }\n }\n _storeStates() {\n let stateIndex = 0;\n let state = localStorage.getItem(`ks.state.${stateIndex}`);\n while (!isNil(state)) {\n localStorage.removeItem(`ks.state.${stateIndex}`);\n state = localStorage.getItem(`ks.state.${++stateIndex}`);\n }\n stateIndex = 0;\n for (const state2 of this.states) {\n localStorage.setItem(`ks.state.${stateIndex++}`, JSON.stringify(state2));\n }\n }\n _refreshGameList() {\n this.gameList.removeChildren(this.gameList.children);\n this.gameList.addChildren(\n this.games.sort(\n (a, b) => new Date(a.unwrap().timestamp).getTime() - new Date(b.unwrap().timestamp).getTime()\n ).map((game2) => [game2.unwrap(), game2]).map(\n ([game2, gameSlot]) => new ButtonListItem(\n this,\n new TextButton(\n this,\n `${game2.label} (${formatDistanceToNow(new Date(game2.timestamp), {\n addSuffix: true,\n locale: this.locale\n })})`,\n {\n onClick: () => {\n this.loadGame(game2.game).catch(redirectErrorsToConsole(console));\n this.host.engine.imessage("state.loaded.game", [game2.label]);\n },\n title: new Date(game2.timestamp).toLocaleString()\n }\n )\n ).addChildren([\n new Container(this, { classes: [stylesLabelListItem.fillSpace] }),\n new IconButton(this, Icons.Save, this.host.engine.i18n("state.update.game"), {\n onClick: () => {\n this.updateGame(gameSlot, this.host.game.save());\n this.host.engine.imessage("state.updated.game", [game2.label]);\n }\n }),\n new IconButton(this, Icons.Edit, this.host.engine.i18n("state.edit.game"), {\n onClick: () => {\n this.storeGame(game2.game);\n this.deleteGame(gameSlot, true);\n this.host.engine.imessage("state.updated.game", [game2.label]);\n }\n }),\n new IconButton(this, Icons.Copy, this.host.engine.i18n("state.copy.game"), {\n onClick: () => {\n this.copyGame(game2.game).catch(redirectErrorsToConsole(console));\n this.host.engine.imessage("state.copied.game", [game2.label]);\n }\n }),\n new IconButton(this, Icons.Delete, this.host.engine.i18n("state.delete.game"), {\n onClick: () => {\n this.deleteGame(gameSlot);\n this.host.engine.imessage("state.deleted.game", [game2.label]);\n }\n })\n ])\n )\n );\n }\n _refreshStateList() {\n this.stateList.removeChildren(this.stateList.children);\n this.stateList.addChildren(\n this.states.sort(\n (a, b) => new Date(a.unwrap().timestamp).getTime() - new Date(b.unwrap().timestamp).getTime()\n ).map((stateSlot) => [stateSlot.unwrap(), stateSlot]).map(\n ([state, stateSlot]) => new ButtonListItem(\n this,\n new TextButton(\n this,\n `${state.label} (${formatDistanceToNow(new Date(state.timestamp), {\n addSuffix: true,\n locale: this.locale\n })})`,\n {\n onClick: () => {\n this.loadState(state.state);\n this.host.engine.imessage("state.loaded.state", [state.label]);\n },\n title: new Date(state.timestamp).toLocaleString()\n }\n )\n ).addChildren([\n new Container(this, { classes: [stylesLabelListItem.fillSpace] }),\n new IconButton(this, Icons.Save, this.host.engine.i18n("state.update.state"), {\n onClick: () => {\n this.updateState(stateSlot, this.host.engine.stateSerialize());\n this.host.engine.imessage("state.updated.state", [state.label]);\n }\n }),\n new IconButton(this, Icons.Edit, this.host.engine.i18n("state.edit.state"), {\n onClick: () => {\n this.storeState(state.state);\n this.deleteState(stateSlot, true);\n this.host.engine.imessage("state.updated.state", [state.label]);\n }\n }),\n new IconButton(this, Icons.Copy, this.host.engine.i18n("state.copy.state"), {\n onClick: () => {\n this.copyState(state.state).catch(redirectErrorsToConsole(console));\n this.host.engine.imessage("state.copied.state", [state.label]);\n }\n }),\n new IconButton(this, Icons.Delete, this.host.engine.i18n("state.delete.state"), {\n onClick: () => {\n this.deleteState(stateSlot);\n this.host.engine.imessage("state.deleted.state", [state.label]);\n }\n })\n ])\n )\n );\n }\n async copyState(state) {\n await this.host.copySettings(state, false);\n }\n async copyGame(game2) {\n const saveData = game2 ?? this.host.game.save();\n const saveDataString = JSON.stringify(saveData);\n const encodedData = this.setting.compress.enabled ? this.host.game.compressLZData(saveDataString) : saveDataString;\n await UserScriptLoader.window.navigator.clipboard.writeText(encodedData);\n }\n /**\n * Request text input from the user, and try to import it.\n *\n * Things users might paste, in no specific order:\n * 1. Kittens Game Save, uncompressed line-agnostic JSON\n * 2. Kittens Game Save, lz-string compressed single-line UTF-8 string\n * 3. Kittens Game Save, lz-string compressed single-line UTF-16 string\n * 4. Kitten Scientists Settings, uncompressed line-agnostic JSON\n * 5. Kitten Scientists Settings, lz-string compressed single-line Base64 string\n * 6. Kitten Scientists Settings Export, multi-line string where all lines are either:\n * - #4, but must be single-line\n * - #5\n * 7. Kitten Scientists Settings Export, multi-line string where each line is\n * an uncompressed JSON string serialization of:\n * {\n * label: "The label the user previously assigned to these settings.",\n * state: "The same options as #6",\n * timestamp: "Last time the settings were modified. As new Date().toISOString().",\n * }\n */\n import() {\n const userInput = UserScriptLoader.window.prompt(this.host.engine.i18n("state.loadPrompt"));\n if (isNil(userInput)) {\n return;\n }\n const importId = (/* @__PURE__ */ new Date()).toDateString();\n let importSequence = 1;\n const makeImportLabel = () => this.host.engine.i18n("state.importedState", [`${importId} #${importSequence++}`]);\n const internalImport = (input) => {\n try {\n const state = KittenScientists.decodeSettings(input);\n this.storeState(state, makeImportLabel());\n this.host.engine.imessage("state.imported.state");\n return;\n } catch (_error) {\n }\n try {\n const subjectData2 = JSON.parse(input);\n const state = KittenScientists.decodeSettings(subjectData2.state);\n this.storeState(state, subjectData2.label);\n this.host.engine.imessage("state.imported.state");\n return;\n } catch (_error) {\n }\n let subjectData;\n try {\n subjectData = JSON.parse(input);\n } catch (_error) {\n const uncompressed = this.host.game.decompressLZData(input);\n try {\n subjectData = JSON.parse(uncompressed);\n } catch (_error2) {\n if (input.match(/\\r?\\n/)) {\n return input.split(/\\r?\\n/).map((line) => void internalImport(line));\n }\n throw new InvalidArgumentError(\n "The provided input can not be parsed as anything we understand."\n );\n }\n }\n let stateLabel;\n if (!isNil(subjectData) && "ks" in subjectData && !isNil(subjectData.ks)) {\n const state = subjectData.ks.state[0];\n stateLabel = this.storeState(state, makeImportLabel()) ?? void 0;\n this.host.engine.imessage("state.imported.state");\n subjectData.ks = void 0;\n }\n this.storeGame(subjectData, stateLabel);\n this.host.engine.imessage("state.imported.game");\n };\n internalImport(userInput);\n }\n storeGame(game2, label2) {\n let gameLabel = label2;\n if (isNil(gameLabel)) {\n gameLabel = UserScriptLoader.window.prompt(this.host.engine.i18n("state.storeGame.prompt")) ?? void 0;\n }\n if (isNil(gameLabel)) {\n return null;\n }\n gameLabel = (gameLabel === "" ? void 0 : gameLabel) ?? this.host.engine.i18n("state.unlabeledGame");\n gameLabel = gameLabel.substring(0, 127);\n this.games.push(\n new Unique({\n game: game2 ?? this.host.game.save(),\n label: gameLabel,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n })\n );\n this._storeGames();\n this.requestRefresh();\n return gameLabel;\n }\n storeState(state, label2) {\n let stateLabel = label2;\n if (isNil(stateLabel)) {\n stateLabel = UserScriptLoader.window.prompt(this.host.engine.i18n("state.storeState.prompt")) ?? void 0;\n }\n if (isNil(stateLabel)) {\n return null;\n }\n stateLabel = (stateLabel === "" ? void 0 : stateLabel) ?? this.host.engine.i18n("state.unlabeledState");\n stateLabel = stateLabel.substring(0, 127);\n this.states.push(\n new Unique({\n label: stateLabel,\n state: state ?? this.host.engine.stateSerialize(),\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n })\n );\n this._storeStates();\n this.requestRefresh();\n return stateLabel;\n }\n storeStateFactoryDefaults() {\n this.storeState(Engine.DEFAULT_STATE);\n }\n storeAutoSave(state) {\n const existing = this.states.find((state2) => state2.unwrap().label === "Auto-Save");\n if (!isNil(existing)) {\n console.info(...cl("Updating existing Auto-Save..."));\n existing.replace({\n ...existing.unwrap(),\n state,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n this._storeStates();\n this.requestRefresh();\n return;\n }\n console.info(...cl("Storing new Auto-Save..."));\n this.storeState(state, "Auto-Save");\n }\n exportStateAll() {\n const statesJson = this.states.map((state) => state.unwrap()).map(\n (state) => JSON.stringify({\n label: state.label,\n state: KittenScientists.encodeSettings(state.state, false),\n timestamp: state.timestamp\n })\n ).join("\\n");\n const a = document.createElement("a");\n const blob = new Blob([statesJson], { type: "application/x-ndjson" });\n const url = URL.createObjectURL(blob);\n a.setAttribute("href", url);\n a.setAttribute("download", `ks-local-states-${Date.now()}.ndjson`);\n a.click();\n }\n async loadGame(game2) {\n if (this._destructiveActionPrevented()) {\n return;\n }\n await new SavegameLoader(this.host.game).loadRaw(game2);\n }\n loadState(state) {\n if (this._destructiveActionPrevented()) {\n return;\n }\n this.host.engine.stateLoad(state, true);\n this.host.refreshEntireUserInterface();\n }\n loadAutoSave() {\n if (this.host.engine.isLoaded) {\n console.info(...cl("Not attempting to load Auto-Save, because a state is already loaded."));\n return;\n }\n const existing = this.states.find((state) => state.unwrap().label === "Auto-Save");\n if (isNil(existing)) {\n console.info(...cl("No Auto-Save settings found."));\n return;\n }\n console.info(...cl("Loading Auto-Save..."));\n this.host.engine.stateLoad(existing.unwrap().state, false);\n }\n updateGame(game2, newGame) {\n if (this._destructiveActionPrevented()) {\n return;\n }\n const label2 = game2.unwrap().label;\n game2.replace({\n game: newGame,\n label: label2,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n this._storeGames();\n this.requestRefresh();\n }\n updateState(state, newState) {\n if (this._destructiveActionPrevented()) {\n return;\n }\n const label2 = state.unwrap().label;\n state.replace({\n label: label2,\n state: newState,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n this._storeStates();\n this.requestRefresh();\n }\n deleteGame(game2, force = false) {\n if (!force && this._destructiveActionPrevented()) {\n return;\n }\n const index = this.games.indexOf(game2);\n if (index < 0) {\n return;\n }\n this.games.splice(index, 1);\n this._storeGames();\n this.requestRefresh();\n }\n deleteState(state, force = false) {\n if (!force && this._destructiveActionPrevented()) {\n return;\n }\n const index = this.states.indexOf(state);\n if (index < 0) {\n return;\n }\n this.states.splice(index, 1);\n this._storeStates();\n this.requestRefresh();\n }\n _destructiveActionPrevented() {\n if (!this.setting.noConfirm.enabled && !UserScriptLoader.window.confirm(this.host.engine.i18n("state.confirmDestruction"))) {\n return true;\n }\n return false;\n }\n }\n class IconSettingsPanel extends CollapsiblePanel {\n /**\n * Constructs a settings panel that can have an icon.\n *\n * @param host A reference to the host.\n * @param label The label to put main checkbox of this section.\n * @param setting An setting for which this is the settings panel.\n * @param options Options for the panel.\n */\n constructor(parent, label2, setting2, options) {\n super(\n parent,\n new LabelListItem(parent, label2, {\n classes: [stylesSettingListItem.checked, stylesSettingListItem.setting],\n icon: options == null ? void 0 : options.icon\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]),\n options\n );\n __publicField(this, "setting");\n this.setting = setting2;\n }\n }\n class ResetBonfireSettingsUi extends IconSettingsPanel {\n constructor(parent, settings, locale) {\n var _a, _b;\n const label2 = parent.host.engine.i18n("ui.build");\n super(parent, label2, settings, {\n icon: Icons.Bonfire,\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && Object.values(settings.buildings).some((_) => _.enabled && _.trigger <= 0);\n }\n });\n __publicField(this, "_buildings");\n this._buildings = [];\n for (const buildingGroup of this.host.game.bld.buildingGroups) {\n this._buildings.push(new HeaderListItem(this, buildingGroup.title));\n for (const building of buildingGroup.buildings) {\n if (building === "unicornPasture" || isNil(this.setting.buildings[building])) {\n continue;\n }\n const meta = this.host.game.bld.getBuildingExt(building).meta;\n if (!isNil(meta.stages)) {\n const name = (_a = Object.values(this.setting.buildings).find(\n (item) => item.baseBuilding === building\n )) == null ? void 0 : _a.building;\n this._buildings.push(\n this._getResetOption(\n this,\n this.setting.buildings[building],\n locale,\n settings,\n meta.stages[0].label\n ),\n this._getResetOption(\n this,\n this.setting.buildings[name],\n locale,\n settings,\n meta.stages[1].label,\n false,\n true\n )\n );\n } else if (!isNil(meta.label)) {\n this._buildings.push(\n this._getResetOption(\n this,\n this.setting.buildings[building],\n locale,\n settings,\n meta.label\n )\n );\n }\n }\n if (buildingGroup !== this.host.game.bld.buildingGroups[this.host.game.bld.buildingGroups.length - 1]) {\n (_b = this._buildings.at(-1)) == null ? void 0 : _b.element.addClass(stylesDelimiter.delimiter);\n }\n }\n const listBuildings = new SettingsList(this);\n listBuildings.addChildren(this._buildings);\n this.addChildContent(listBuildings);\n }\n _getResetOption(parent, option, locale, sectionSetting, label2, delimiter2 = false, upgradeIndicator = false) {\n const element = new SettingTriggerListItem(parent, option, locale, label2, {\n delimiter: delimiter2,\n onCheck: () => {\n parent.host.engine.imessage("status.reset.check.enable", [label2]);\n },\n onRefreshRequest: () => {\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = sectionSetting.enabled && option.enabled && option.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.absolute"),\n parent.host.engine.i18n("ui.trigger.build.prompt", [\n label2,\n option.trigger !== -1 ? parent.host.renderAbsolute(option.trigger, locale.selected) : parent.host.engine.i18n("ui.trigger.inactive")\n ]),\n option.trigger !== -1 ? parent.host.renderAbsolute(option.trigger) : "",\n parent.host.engine.i18n("ui.trigger.reset.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n option.enabled = false;\n return;\n }\n option.trigger = Number(value);\n },\n onUnCheck: () => {\n parent.host.engine.imessage("status.reset.check.disable", [label2]);\n },\n upgradeIndicator\n });\n element.triggerButton.element.addClass(stylesButton.lastHeadAction);\n return element;\n }\n }\n class ResetReligionSettingsUi extends IconSettingsPanel {\n constructor(parent, settings, locale) {\n const label2 = parent.host.engine.i18n("ui.faith");\n super(parent, label2, settings, {\n icon: Icons.Religion,\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && Object.values(settings.buildings).some((_) => _.enabled && _.trigger <= 0);\n }\n });\n this.addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]);\n const unicornsArray = [...UnicornItems];\n this.addChildContent(\n new SettingsList(this).addChildren([\n new HeaderListItem(this, this.host.engine.i18n("$religion.panel.ziggurat.label")),\n this._getResetOption(\n this,\n this.setting.buildings.unicornPasture,\n locale,\n settings,\n this.host.engine.i18n("$buildings.unicornPasture.label")\n ),\n ...this.host.game.religion.zigguratUpgrades.filter(\n (item) => unicornsArray.includes(item.name) && !isNil(this.setting.buildings[item.name])\n ).map(\n (zigguratUpgrade) => this._getResetOption(\n this,\n this.setting.buildings[zigguratUpgrade.name],\n locale,\n settings,\n zigguratUpgrade.label\n )\n ),\n new Delimiter(this),\n ...this.host.game.religion.zigguratUpgrades.filter(\n (item) => !unicornsArray.includes(item.name) && !isNil(this.setting.buildings[item.name])\n ).map(\n (upgrade) => this._getResetOption(\n this,\n this.setting.buildings[upgrade.name],\n locale,\n settings,\n upgrade.label\n )\n ),\n new Delimiter(this),\n new HeaderListItem(this, this.host.engine.i18n("$religion.panel.orderOfTheSun.label")),\n ...this.host.game.religion.religionUpgrades.filter((item) => !isNil(this.setting.buildings[item.name])).map(\n (upgrade) => {\n var _a;\n return this._getResetOption(\n this,\n this.setting.buildings[upgrade.name],\n locale,\n settings,\n upgrade.label,\n upgrade.name === ((_a = this.host.game.religion.religionUpgrades.at(-1)) == null ? void 0 : _a.name)\n );\n }\n ),\n new HeaderListItem(this, this.host.engine.i18n("$religion.panel.cryptotheology.label")),\n ...this.host.game.religion.transcendenceUpgrades.filter((item) => !isNil(this.setting.buildings[item.name])).map(\n (upgrade) => this._getResetOption(\n this,\n this.setting.buildings[upgrade.name],\n locale,\n settings,\n upgrade.label\n )\n )\n ])\n );\n }\n _getResetOption(parent, option, locale, sectionSetting, label2, delimiter2 = false, upgradeIndicator = false) {\n const element = new SettingTriggerListItem(parent, option, locale, label2, {\n delimiter: delimiter2,\n onCheck: () => {\n parent.host.engine.imessage("status.reset.check.enable", [label2]);\n },\n onRefreshRequest: () => {\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = sectionSetting.enabled && option.enabled && option.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.absolute"),\n parent.host.engine.i18n("ui.trigger.build.prompt", [\n label2,\n option.trigger !== -1 ? parent.host.renderAbsolute(option.trigger, locale.selected) : parent.host.engine.i18n("ui.trigger.inactive")\n ]),\n option.trigger !== -1 ? parent.host.renderAbsolute(option.trigger) : "",\n parent.host.engine.i18n("ui.trigger.reset.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n option.enabled = false;\n return;\n }\n option.trigger = Number(value);\n },\n onUnCheck: () => {\n parent.host.engine.imessage("status.reset.check.disable", [label2]);\n },\n upgradeIndicator\n });\n element.triggerButton.element.addClass(stylesButton.lastHeadAction);\n return element;\n }\n }\n class ResetResourcesSettingsUi extends IconSettingsPanel {\n constructor(parent, settings, locale) {\n const label2 = parent.host.engine.i18n("ui.resources");\n super(parent, label2, settings, {\n icon: Icons.Resources,\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && Object.values(settings.resources).some((_) => _.enabled && _.trigger < 0);\n }\n });\n this.addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]);\n const resources = this.host.game.resPool.resources;\n const items = [];\n let lastLabel = resources[0].title;\n for (const resource of [...resources].sort(\n (a, b) => a.title.localeCompare(b.title, locale.selected)\n )) {\n const option = this.setting.resources[resource.name];\n const element = new SettingTriggerListItem(this, option, locale, ucfirst(resource.title), {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [resource.title]);\n },\n onRefreshRequest: () => {\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = settings.enabled && option.enabled && option.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.trigger.prompt.float"),\n this.host.engine.i18n("ui.trigger.build.prompt", [\n resource.title,\n option.trigger !== -1 ? this.host.renderAbsolute(option.trigger, locale.selected) : this.host.engine.i18n("ui.trigger.inactive")\n ]),\n option.trigger !== -1 ? this.host.renderAbsolute(option.trigger) : "",\n this.host.engine.i18n("ui.trigger.reset.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n option.enabled = false;\n return;\n }\n option.trigger = parent.host.parseAbsolute(value) ?? option.trigger;\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [resource.title]);\n }\n });\n element.triggerButton.element.addClass(stylesButton.lastHeadAction);\n if (this.host.engine.localeSupportsFirstLetterSplits(locale.selected)) {\n if (lastLabel[0] !== resource.title[0]) {\n element.element.addClass(stylesLabelListItem.splitter);\n }\n }\n items.push(element);\n lastLabel = resource.title;\n }\n this.addChildContent(new SettingsList(this).addChildren(items));\n }\n }\n class ResetSpaceSettingsUi extends IconSettingsPanel {\n constructor(parent, settings, locale) {\n const label2 = parent.host.engine.i18n("ui.space");\n super(parent, label2, settings, {\n icon: Icons.Space,\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && Object.values(settings.buildings).some((_) => _.enabled && _.trigger <= 0);\n }\n });\n this.addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]);\n this.addChildContent(\n new SettingsList(this).addChildren(\n this.host.game.space.planets.filter((plant) => 0 < plant.buildings.length).flatMap((planet, indexPlanet, arrayPlant) => [\n new HeaderListItem(this, this.host.engine.labelForPlanet(planet.name)),\n ...planet.buildings.filter((item) => !isNil(this.setting.buildings[item.name])).map(\n (building, indexBuilding, arrayBuilding) => this._getResetOption(\n this,\n this.setting.buildings[building.name],\n locale,\n settings,\n building.label,\n indexPlanet < arrayPlant.length - 1 && indexBuilding === arrayBuilding.length - 1\n )\n )\n ])\n )\n );\n }\n _getResetOption(parent, option, locale, sectionSetting, label2, delimiter2 = false, upgradeIndicator = false) {\n const element = new SettingTriggerListItem(parent, option, locale, label2, {\n delimiter: delimiter2,\n onCheck: () => {\n parent.host.engine.imessage("status.reset.check.enable", [label2]);\n },\n onRefreshRequest: () => {\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = sectionSetting.enabled && option.enabled && option.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.absolute"),\n parent.host.engine.i18n("ui.trigger.build.prompt", [\n label2,\n option.trigger !== -1 ? parent.host.renderAbsolute(option.trigger, locale.selected) : parent.host.engine.i18n("ui.trigger.inactive")\n ]),\n option.trigger !== -1 ? parent.host.renderAbsolute(option.trigger) : "",\n parent.host.engine.i18n("ui.trigger.reset.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n option.enabled = false;\n return;\n }\n option.trigger = Number(value);\n },\n onUnCheck: () => {\n parent.host.engine.imessage("status.reset.check.disable", [label2]);\n },\n upgradeIndicator\n });\n element.triggerButton.element.addClass(stylesButton.lastHeadAction);\n return element;\n }\n }\n class ResetTimeSettingsUi extends IconSettingsPanel {\n constructor(parent, settings, locale) {\n const label2 = parent.host.engine.i18n("ui.time");\n super(parent, label2, settings, {\n icon: Icons.Time,\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && Object.values(settings.buildings).some((_) => _.enabled && _.trigger <= 0);\n }\n });\n this.addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]);\n this.addChildContent(\n new SettingsList(this).addChildren([\n new HeaderListItem(this, this.host.engine.i18n("$workshop.chronoforge.label")),\n ...this.host.game.time.chronoforgeUpgrades.filter((item) => !isNil(this.setting.buildings[item.name])).map(\n (building) => {\n var _a;\n return this._getResetOption(\n this,\n this.setting.buildings[building.name],\n locale,\n settings,\n building.label,\n building.name === ((_a = this.host.game.time.chronoforgeUpgrades.at(-1)) == null ? void 0 : _a.name)\n );\n }\n ),\n new HeaderListItem(this, this.host.engine.i18n("$science.voidSpace.label")),\n ...this.host.game.time.voidspaceUpgrades.filter((item) => item.name in this.setting.buildings).map(\n (building) => this._getResetOption(\n this,\n this.setting.buildings[building.name],\n locale,\n settings,\n building.label\n )\n )\n ])\n );\n }\n _getResetOption(parent, option, locale, sectionSetting, label2, delimiter2 = false, upgradeIndicator = false) {\n const element = new SettingTriggerListItem(parent, option, locale, label2, {\n delimiter: delimiter2,\n onCheck: () => {\n parent.host.engine.imessage("status.reset.check.enable", [label2]);\n },\n onRefreshRequest: () => {\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = sectionSetting.enabled && option.enabled && option.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.absolute"),\n parent.host.engine.i18n("ui.trigger.build.prompt", [\n label2,\n option.trigger !== -1 ? parent.host.renderAbsolute(option.trigger, locale.selected) : parent.host.engine.i18n("ui.trigger.inactive")\n ]),\n option.trigger !== -1 ? parent.host.renderAbsolute(option.trigger) : "",\n parent.host.engine.i18n("ui.trigger.reset.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n option.enabled = false;\n return;\n }\n option.trigger = Number(value);\n },\n onUnCheck: () => {\n parent.host.engine.imessage("status.reset.check.disable", [label2]);\n },\n upgradeIndicator\n });\n element.triggerButton.element.addClass(stylesButton.lastHeadAction);\n return element;\n }\n }\n class ResetUpgradesSettingsUi extends IconSettingsPanel {\n constructor(parent, settings, locale) {\n const label2 = parent.host.engine.i18n("ui.upgrades");\n super(parent, label2, settings, {\n icon: Icons.Workshop\n });\n this.addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]);\n const upgrades = this.host.game.workshop.upgrades.filter(\n (upgrade) => !isNil(this.setting.upgrades[upgrade.name])\n );\n const items = [];\n let lastLabel = upgrades[0].label;\n let lastElement;\n for (const upgrade of upgrades.sort(\n (a, b) => a.label.localeCompare(b.label, locale.selected)\n )) {\n const option = this.setting.upgrades[upgrade.name];\n const element = this._getResetOption(this, option, upgrade.label);\n if (this.host.engine.localeSupportsFirstLetterSplits(locale.selected)) {\n if (lastLabel[0] !== upgrade.label[0]) {\n if (!isNil(lastElement)) {\n lastElement.element.addClass(stylesDelimiter.delimiter);\n }\n element.element.addClass(stylesLabelListItem.splitter);\n }\n }\n lastElement = element;\n items.push(element);\n lastLabel = upgrade.label;\n }\n this.addChildContent(new SettingsList(this).addChildren(items));\n }\n _getResetOption(parent, option, label2, delimiter2 = false, upgradeIndicator = false) {\n return new SettingListItem(parent, option, label2, {\n delimiter: delimiter2,\n onCheck: () => {\n parent.host.engine.imessage("status.reset.check.enable", [label2]);\n },\n onUnCheck: () => {\n parent.host.engine.imessage("status.reset.check.disable", [label2]);\n },\n upgradeIndicator\n });\n }\n }\n class ResetSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n const label2 = parent.host.engine.i18n("option.time.reset");\n super(\n parent,\n settings,\n new SettingListItem(parent, settings, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]),\n {\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && [\n this._bonfireUi,\n this._religionUi,\n this._resourcesUi,\n this._spaceUi,\n this._timeUi,\n this._upgradesUi\n ].some((_) => _.expando.ineffective);\n }\n }\n );\n __publicField(this, "_bonfireUi");\n __publicField(this, "_religionUi");\n __publicField(this, "_resourcesUi");\n __publicField(this, "_spaceUi");\n __publicField(this, "_timeUi");\n __publicField(this, "_upgradesUi");\n const list2 = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n });\n this._bonfireUi = new ResetBonfireSettingsUi(this, this.setting.bonfire, locale);\n this._religionUi = new ResetReligionSettingsUi(this, this.setting.religion, locale);\n this._resourcesUi = new ResetResourcesSettingsUi(this, this.setting.resources, locale);\n this._spaceUi = new ResetSpaceSettingsUi(this, this.setting.space, locale);\n this._timeUi = new ResetTimeSettingsUi(this, this.setting.time, locale);\n this._upgradesUi = new ResetUpgradesSettingsUi(this, this.setting.upgrades, locale);\n list2.addChildren([\n this._bonfireUi,\n this._religionUi,\n this._resourcesUi,\n this._spaceUi,\n this._timeUi,\n this._upgradesUi\n ]);\n this.addChildContent(list2);\n }\n }\n class CyclesList extends SettingsList {\n /**\n * Constructs a `SeasonsList`.\n *\n * @param host A reference to the host.\n * @param setting The settings that correlate to this list.\n * @param behavior Control cycle check box log output\n * @param options Options for this list.\n */\n constructor(parent, setting2, options) {\n super(parent, options);\n __publicField(this, "setting");\n this.setting = setting2;\n const makeCycle = (cycle, setting22) => {\n const label2 = parent.host.engine.labelForCycle(cycle);\n return new SettingListItem(parent, setting22, label2, {\n onCheck: (isBatchProcess) => {\n var _a;\n (_a = options == null ? void 0 : options.onCheckCycle) == null ? void 0 : _a.call(options, label2, setting22, isBatchProcess);\n },\n onUnCheck: (isBatchProcess) => {\n var _a;\n (_a = options == null ? void 0 : options.onUnCheckCycle) == null ? void 0 : _a.call(options, label2, setting22, isBatchProcess);\n }\n });\n };\n const cycles = [\n makeCycle("charon", this.setting.charon),\n makeCycle("umbra", this.setting.umbra),\n makeCycle("yarn", this.setting.yarn),\n makeCycle("helios", this.setting.helios),\n makeCycle("cath", this.setting.cath),\n makeCycle("redmoon", this.setting.redmoon),\n makeCycle("dune", this.setting.dune),\n makeCycle("piscine", this.setting.piscine),\n makeCycle("terminus", this.setting.terminus),\n makeCycle("kairo", this.setting.kairo)\n ];\n this.addChildren(cycles);\n this.element[0].addEventListener("enableAll", () => {\n for (const cycle of cycles) {\n cycle.check(true);\n }\n });\n this.element[0].addEventListener("disableAll", () => {\n for (const cycle of cycles) {\n cycle.uncheck(true);\n }\n });\n }\n }\n class SeasonsList extends SettingsList {\n /**\n * Constructs a `SeasonsList`.\n *\n * @param host A reference to the host.\n * @param setting The settings that correlate to this list.\n * @param options Options for this list\n */\n constructor(parent, setting2, options) {\n super(parent, options);\n __publicField(this, "setting");\n __publicField(this, "spring");\n __publicField(this, "summer");\n __publicField(this, "autumn");\n __publicField(this, "winter");\n this.setting = setting2;\n const makeSeason = (label2, setting22) => {\n return new SettingListItem(this, setting22, label2, {\n onCheck: (isBatchProcess) => {\n var _a;\n (_a = options == null ? void 0 : options.onCheckSeason) == null ? void 0 : _a.call(options, label2, setting22, isBatchProcess);\n },\n onUnCheck: (isBatchProcess) => {\n var _a;\n (_a = options == null ? void 0 : options.onUnCheckSeason) == null ? void 0 : _a.call(options, label2, setting22, isBatchProcess);\n }\n });\n };\n this.spring = makeSeason(this.host.engine.i18n("$calendar.season.spring"), this.setting.spring);\n this.summer = makeSeason(this.host.engine.i18n("$calendar.season.summer"), this.setting.summer);\n this.autumn = makeSeason(this.host.engine.i18n("$calendar.season.autumn"), this.setting.autumn);\n this.winter = makeSeason(this.host.engine.i18n("$calendar.season.winter"), this.setting.winter);\n this.addChildren([this.spring, this.summer, this.autumn, this.winter]);\n }\n toString() {\n return `[${SeasonsList.name}#${this.componentId}]`;\n }\n }\n class TimeSkipHeatSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale, sectionSetting, sectionParentSetting) {\n const label2 = parent.host.engine.i18n("option.time.activeHeatTransfer");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.activeHeatTransfer.prompt"),\n parent.host.engine.i18n("ui.trigger.activeHeatTransfer.promptTitle", [\n parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]),\n parent.host.renderPercentage(settings.trigger),\n parent.host.engine.i18n("ui.trigger.activeHeatTransfer.promptExplainer")\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n settings.activeHeatTransferStatus.enabled = false;\n }\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled;\n this.settingItem.triggerButton.ineffective = sectionParentSetting.enabled && sectionSetting.enabled && settings.enabled && settings.trigger === -1;\n this.expando.ineffective = sectionParentSetting.enabled && sectionSetting.enabled && settings.enabled && !Object.values(settings.cycles).some((cycle) => cycle.enabled);\n if (settings.activeHeatTransferStatus.enabled) {\n this.head.elementLabel.attr("data-ks-active-from", "◎");\n this.head.elementLabel.attr("data-ks-active-to", "◎");\n this.head.elementLabel.addClass(styles$3.active);\n } else {\n this.head.elementLabel.removeClass(styles$3.active);\n }\n }\n }\n );\n this.addChildContent(\n new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([\n new CyclesList(this, this.setting.cycles, {\n onCheckCycle: (label22) => {\n this.host.engine.imessage("time.heatTransfer.cycle.enable", [label22]);\n },\n onUnCheckCycle: (label22) => {\n this.host.engine.imessage("time.heatTransfer.cycle.disable", [label22]);\n }\n })\n ])\n );\n }\n }\n class TimeSkipSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale, sectionSetting) {\n const label2 = parent.host.engine.i18n("option.time.skip");\n super(\n parent,\n settings,\n new SettingMaxTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefreshMax() {\n this.maxButton.updateLabel(parent.host.renderAbsolute(settings.max));\n this.maxButton.element[0].title = settings.max < 0 ? parent.host.engine.i18n("ui.max.timeSkip.titleInfinite", [label2]) : settings.max === 0 ? parent.host.engine.i18n("ui.max.timeSkip.titleZero", [label2]) : parent.host.engine.i18n("ui.max.timeSkip.title", [\n parent.host.renderAbsolute(settings.max),\n label2\n ]);\n },\n onRefreshTrigger() {\n this.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger", [\n settings.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.inactive") : `${parent.host.renderFloat(settings.trigger, locale.selected)} TC`\n ]);\n },\n onSetMax: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.max.timeSkip.prompt"),\n parent.host.engine.i18n("ui.max.timeSkip.promptTitle", [\n parent.host.renderAbsolute(settings.max, locale.selected)\n ]),\n parent.host.renderAbsolute(settings.max),\n parent.host.engine.i18n("ui.max.timeSkip.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.max = -1;\n return;\n }\n if (value === "0") {\n settings.enabled = false;\n }\n settings.max = parent.host.parseAbsolute(value) ?? settings.max;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.timeSkip.prompt"),\n parent.host.engine.i18n("ui.trigger.timeSkip.promptTitle", [\n parent.host.renderAbsolute(settings.trigger, locale.selected)\n ]),\n parent.host.renderAbsolute(settings.trigger),\n parent.host.engine.i18n("ui.trigger.timeSkip.promptExplainer")\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n settings.trigger = parent.host.parseAbsolute(value) ?? settings.trigger;\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.maxButton.inactive = !settings.enabled || settings.max === -1;\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger === -1;\n this.settingItem.maxButton.ineffective = sectionSetting.enabled && settings.enabled && settings.max === 0;\n this._cycles.expando.ineffective = sectionSetting.enabled && settings.enabled && !Object.values(settings.cycles).some((cycle) => cycle.enabled);\n this._seasons.expando.ineffective = sectionSetting.enabled && settings.enabled && !Object.values(settings.seasons).some((season) => season.enabled);\n }\n }\n );\n __publicField(this, "_cycles");\n __publicField(this, "_seasons");\n __publicField(this, "_activeHeatTransferUI");\n this.settingItem.triggerButton.element.removeClass(stylesButton.lastHeadAction);\n this._cycles = new CollapsiblePanel(\n this,\n new LabelListItem(this, ucfirst(this.host.engine.i18n("ui.cycles")), {\n classes: [stylesSettingListItem.checked, stylesSettingListItem.setting],\n icon: Icons.Cycles\n }).addChildrenHead([new Container(this, { classes: [stylesLabelListItem.fillSpace] })])\n ).addChildrenContent([\n new CyclesList(this, this.setting.cycles, {\n onCheckCycle: (label22) => {\n this.host.engine.imessage("time.skip.cycle.enable", [label22]);\n },\n onUnCheckCycle: (label22) => {\n this.host.engine.imessage("time.skip.cycle.disable", [label22]);\n }\n })\n ]);\n this._seasons = new CollapsiblePanel(\n this,\n new LabelListItem(this, ucfirst(this.host.engine.i18n("trade.seasons")), {\n classes: [stylesSettingListItem.checked, stylesSettingListItem.setting],\n icon: Icons.Seasons\n }).addChildrenHead([new Container(this, { classes: [stylesLabelListItem.fillSpace] })])\n ).addChildrenContent([\n new SeasonsList(this, this.setting.seasons, {\n onCheckSeason: (label22) => {\n this.host.engine.imessage("time.skip.season.enable", [label22]);\n },\n onUnCheckSeason: (label22) => {\n this.host.engine.imessage("time.skip.season.disable", [label22]);\n }\n })\n ]);\n this._activeHeatTransferUI = new TimeSkipHeatSettingsUi(\n this,\n this.setting.activeHeatTransfer,\n locale,\n settings,\n sectionSetting\n );\n this.addChildContent(\n new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([\n this._cycles,\n this._seasons,\n new SettingListItem(\n this,\n this.setting.ignoreOverheat,\n this.host.engine.i18n("option.time.skip.ignoreOverheat")\n ),\n this._activeHeatTransferUI\n ])\n );\n }\n }\n class TimeControlSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${TimeControlSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.timeCtrl");\n super(\n parent,\n settings,\n new SettingListItem(parent, settings, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]),\n {\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && [this._timeSkipUi, this._resetUi].some((_) => _.expando.ineffective);\n }\n }\n );\n __publicField(this, "_items");\n __publicField(this, "_accelerateTime");\n __publicField(this, "_timeSkipUi");\n __publicField(this, "_resetUi");\n const list2 = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n });\n const accelerateLabel = this.host.engine.i18n("option.accelerate");\n this._accelerateTime = new SettingTriggerListItem(\n this,\n this.setting.accelerateTime,\n locale,\n accelerateLabel,\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [accelerateLabel]);\n },\n onRefresh: () => {\n this._accelerateTime.triggerButton.inactive = !this.setting.accelerateTime.enabled;\n this._accelerateTime.triggerButton.ineffective = this.setting.enabled && this.setting.accelerateTime.enabled && this.setting.accelerateTime.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.trigger.accelerateTime.prompt"),\n this.host.engine.i18n("ui.trigger.accelerateTime.promptTitle", [\n this.host.renderPercentage(\n this.setting.accelerateTime.trigger,\n locale.selected,\n true\n )\n ]),\n this.host.renderPercentage(this.setting.accelerateTime.trigger),\n this.host.engine.i18n("ui.trigger.accelerateTime.promptExplainer")\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n this.setting.accelerateTime.trigger = this.host.parsePercentage(value);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [accelerateLabel]);\n }\n }\n );\n this._accelerateTime.triggerButton.element.addClass(stylesButton.lastHeadAction);\n this._timeSkipUi = new TimeSkipSettingsUi(this, this.setting.timeSkip, locale, settings);\n this._resetUi = new ResetSettingsUi(this, this.setting.reset, locale);\n this._items = [this._accelerateTime, this._timeSkipUi, this._resetUi];\n list2.addChildren(this._items);\n this.addChildContent(list2);\n }\n }\n class TimeSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${TimeSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.time");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefresh: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger === -1;\n },\n onRefreshTrigger() {\n this.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger.section", [\n settings.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.inactive") : parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger, locale.selected, true) : parent.host.engine.i18n("ui.infinity")\n ]),\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.trigger = -1;\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger < 0;\n this.settingItem.triggerButton.ineffective = settings.enabled && settings.trigger < 0 && Object.values(settings.buildings).some((_) => _.enabled && 0 < _.max && _.trigger < 0);\n this.expando.ineffective = settings.enabled && Object.values(settings.buildings).some(\n (_) => _.enabled && (0 === _.max || _.trigger < 0 && settings.trigger < 0)\n );\n }\n }\n );\n this.addChildrenContent([\n new SettingsList(this).addChildren([\n new HeaderListItem(this, this.host.engine.i18n("$workshop.chronoforge.label")),\n ...this.host.game.time.chronoforgeUpgrades.filter((item) => !isNil(this.setting.buildings[item.name])).map(\n (building) => {\n var _a;\n return BuildSectionTools.getBuildOption(\n this,\n this.setting.buildings[building.name],\n locale,\n this.setting,\n building.label,\n label2,\n {\n delimiter: building.name === ((_a = this.host.game.time.chronoforgeUpgrades.at(-1)) == null ? void 0 : _a.name),\n renderLabelTrigger: false\n }\n );\n }\n ),\n new HeaderListItem(this, this.host.engine.i18n("$science.voidSpace.label")),\n ...this.host.game.time.voidspaceUpgrades.filter((item) => item.name in this.setting.buildings).map(\n (building) => BuildSectionTools.getBuildOption(\n this,\n this.setting.buildings[building.name],\n locale,\n this.setting,\n building.label,\n label2,\n { renderLabelTrigger: false }\n )\n )\n ]),\n new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([\n new HeaderListItem(this, this.host.engine.i18n("ui.additional")),\n new SettingListItem(\n this,\n this.setting.fixCryochambers,\n this.host.engine.i18n("option.fix.cry"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.fix.cry")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.fix.cry")\n ]);\n }\n }\n )\n ])\n ]);\n }\n }\n const buyButton = "_buyButton_10eul_1";\n const styles$2 = {\n buyButton\n };\n class BuyButton extends TextButton {\n constructor(parent, setting2, locale, options) {\n super(parent, void 0, {\n onClick: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("blackcoin.buy.prompt"),\n parent.host.engine.i18n("blackcoin.buy.promptTitle", [\n parent.host.renderAbsolute(setting2.buy, locale.selected)\n ]),\n parent.host.renderAbsolute(setting2.buy),\n parent.host.engine.i18n("blackcoin.buy.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n setting2.buy = -1;\n return;\n }\n setting2.buy = parent.host.parseAbsolute(value) ?? setting2.buy;\n },\n onRefresh: () => {\n var _a;\n this.element.prop(\n "title",\n this.host.engine.i18n("blackcoin.buy.title", [\n this.host.renderAbsolute(this.setting.buy)\n ])\n );\n this.element.text(\n this.host.engine.i18n("blackcoin.buy", [this.host.renderAbsolute(this.setting.buy)])\n );\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(this);\n }\n });\n __publicField(this, "setting");\n this.element.addClass(styles$2.buyButton);\n this.setting = setting2;\n }\n toString() {\n return `[${BuyButton.name}#${this.componentId}]`;\n }\n }\n const sellButton = "_sellButton_1tmvd_1";\n const styles$1 = {\n sellButton\n };\n class SellButton extends TextButton {\n constructor(parent, setting2, locale, options) {\n super(parent, void 0, {\n onClick: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("blackcoin.sell.prompt"),\n parent.host.engine.i18n("blackcoin.sell.promptTitle", [\n parent.host.renderAbsolute(setting2.sell, locale.selected)\n ]),\n parent.host.renderAbsolute(setting2.sell),\n parent.host.engine.i18n("blackcoin.sell.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n setting2.sell = -1;\n return;\n }\n setting2.sell = parent.host.parseAbsolute(value) ?? setting2.sell;\n },\n onRefresh: () => {\n var _a;\n this.element.prop(\n "title",\n this.host.engine.i18n("blackcoin.sell.title", [\n this.host.renderAbsolute(this.setting.sell)\n ])\n );\n this.element.text(\n this.host.engine.i18n("blackcoin.sell", [this.host.renderAbsolute(this.setting.sell)])\n );\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(options);\n }\n });\n __publicField(this, "setting");\n this.element.addClass(styles$1.sellButton);\n this.setting = setting2;\n }\n toString() {\n return `[${SellButton.name}#${this.componentId}]`;\n }\n }\n class LimitedButton extends Button {\n constructor(parent, setting2, options) {\n super(parent, "", Icons.Eco, {\n border: false,\n classes: [],\n onClick: () => {\n var _a, _b;\n this.setting.limited = !this.setting.limited;\n if (this.setting.limited) {\n (_a = options == null ? void 0 : options.onLimitedCheck) == null ? void 0 : _a.call(this);\n } else {\n (_b = options == null ? void 0 : options.onLimitedUnCheck) == null ? void 0 : _b.call(this);\n }\n },\n onRefresh: () => {\n var _a;\n this.updateTitle(\n this.host.engine.i18n(this.setting.limited ? "ui.limited.on" : "ui.limited.off")\n );\n if (this.setting.limited && !this.inactive) {\n this.element.removeClass(stylesButton.inactive);\n } else {\n this.element.addClass(stylesButton.inactive);\n }\n (_a = options == null ? void 0 : options.onRefresh) == null ? void 0 : _a.call(this);\n }\n });\n __publicField(this, "setting");\n this.setting = setting2;\n for (const className of (options == null ? void 0 : options.classes) ?? []) {\n this.element.addClass(className);\n }\n }\n toString() {\n return `[${LimitedButton.name}#${this.componentId}]`;\n }\n }\n class SettingLimitedListItem extends SettingListItem {\n /**\n * Create a UI element for a setting that can be limited.\n * This will result in an element with a checkbox that has a "Limited" label.\n *\n * @param host The userscript instance.\n * @param label The label for the setting.\n * @param setting The setting model.\n * @param options Options for the list item.\n */\n constructor(parent, setting2, label2, options) {\n super(parent, setting2, label2, options);\n __publicField(this, "limitedButton");\n this.limitedButton = new LimitedButton(parent, setting2, {\n border: false,\n onLimitedCheck: (options == null ? void 0 : options.onLimitedCheck) ? () => {\n var _a;\n return (_a = options.onLimitedCheck) == null ? void 0 : _a.call(this);\n } : void 0,\n onLimitedUnCheck: (options == null ? void 0 : options.onLimitedUnCheck) ? () => {\n var _a;\n return (_a = options.onLimitedUnCheck) == null ? void 0 : _a.call(this);\n } : void 0\n });\n this.addChildrenHead([\n new Container(parent, { classes: [stylesLabelListItem.fillSpace] }),\n this.limitedButton\n ]);\n }\n toString() {\n return `[${SettingLimitedListItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n }\n class SettingLimitedTriggerListItem extends SettingLimitedListItem {\n constructor(parent, setting2, locale, label2, options) {\n super(parent, setting2, label2, options);\n __publicField(this, "triggerButton");\n this.triggerButton = new TriggerButton(parent, setting2, locale, {\n border: false,\n onClick: async () => {\n await options.onSetTrigger.call(this);\n },\n onRefresh: (options == null ? void 0 : options.onRefreshTrigger) ? () => {\n var _a;\n return (_a = options.onRefreshTrigger) == null ? void 0 : _a.call(this);\n } : void 0,\n renderLabel: (options == null ? void 0 : options.renderLabelTrigger) ?? true\n });\n this.addChildHead(this.triggerButton);\n }\n toString() {\n return `[${SettingLimitedTriggerListItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n }\n class SettingMaxListItem extends SettingListItem {\n /**\n * Create a UI element for a setting that can have a maximum.\n * This will result in an element with a labeled checkbox and a "Max" indicator,\n * which controls the respective `max` property in the setting model.\n *\n * @param host The userscript instance.\n * @param label The label for the setting.\n * @param setting The setting model.\n * @param options Options for the list item.\n */\n constructor(parent, setting2, label2, options) {\n super(parent, setting2, label2, options);\n __publicField(this, "maxButton");\n this.maxButton = new MaxButton(parent, setting2, {\n border: false,\n onClick: async () => {\n await options.onSetMax.call(this);\n },\n onRefresh: (options == null ? void 0 : options.onRefreshMax) ? () => {\n var _a;\n return (_a = options.onRefreshMax) == null ? void 0 : _a.call(this);\n } : void 0\n });\n this.addChildrenHead([\n new Container(parent, { classes: [stylesLabelListItem.fillSpace] }),\n this.maxButton\n ]);\n }\n toString() {\n return `[${SettingMaxListItem.name}#${this.componentId}]: \'${this.elementLabel.text()}\'`;\n }\n }\n class EmbassySettingsUi extends SettingsPanel {\n constructor(parent, settings, locale, sectionSetting) {\n const label2 = parent.host.engine.i18n("option.embassies");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.embassies.prompt"),\n parent.host.engine.i18n("ui.trigger.embassies.promptTitle", [\n parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]),\n parent.host.renderPercentage(settings.trigger),\n parent.host.engine.i18n("ui.trigger.embassies.promptExplainer")\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled;\n this.settingItem.triggerButton.ineffective = settings.enabled && settings.trigger === -1;\n this.expando.ineffective = sectionSetting.enabled && settings.enabled && !Object.values(settings.races).some((race) => race.enabled);\n }\n }\n );\n const listRaces = new SettingsList(this).addChildren(\n this.host.game.diplomacy.races.filter((item) => item.name !== "leviathans" && !isNil(this.setting.races[item.name])).map(\n (race) => this._makeEmbassySetting(\n this,\n this.setting.races[race.name],\n locale.selected,\n settings,\n race.title\n )\n )\n );\n this.addChildContent(listRaces);\n }\n _makeEmbassySetting(parent, option, locale, sectionSetting, label2) {\n const onSetMax = async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.max.prompt.absolute"),\n parent.host.engine.i18n("ui.max.build.prompt", [\n label2,\n parent.host.renderAbsolute(option.max, locale)\n ]),\n parent.host.renderAbsolute(option.max),\n parent.host.engine.i18n("ui.max.build.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.max = -1;\n return;\n }\n if (value === "0") {\n option.enabled = false;\n }\n option.max = parent.host.parseAbsolute(value) ?? option.max;\n };\n const element = new SettingMaxListItem(parent, option, label2, {\n onCheck: (isBatchProcess) => {\n parent.host.engine.imessage("status.sub.enable", [label2]);\n if (option.max === 0 && !isBatchProcess) {\n return onSetMax();\n }\n },\n onRefresh: () => {\n element.maxButton.inactive = !option.enabled || option.max === -1;\n element.maxButton.ineffective = sectionSetting.enabled && option.enabled && option.max === 0;\n },\n onRefreshMax: () => {\n element.maxButton.updateLabel(parent.host.renderAbsolute(option.max));\n element.maxButton.element[0].title = option.max < 0 ? parent.host.engine.i18n("ui.max.embassy.titleInfinite", [label2]) : option.max === 0 ? parent.host.engine.i18n("ui.max.embassy.titleZero", [label2]) : parent.host.engine.i18n("ui.max.embassy.title", [\n parent.host.renderAbsolute(option.max),\n label2\n ]);\n },\n onSetMax,\n onUnCheck: () => {\n parent.host.engine.imessage("status.sub.disable", [label2]);\n }\n });\n element.maxButton.element.addClass(stylesButton.lastHeadAction);\n return element;\n }\n }\n class TradeSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${TradeSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.trade");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefreshTrigger() {\n this.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger.section", [\n settings.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.inactive") : parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger, locale.selected, true) : parent.host.engine.i18n("ui.infinity")\n ]),\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.trigger = -1;\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger === -1;\n this.settingItem.triggerButton.ineffective = settings.enabled && settings.trigger < 0 && Object.values(settings.races).some((_) => _.enabled && _.trigger < 0);\n this.expando.ineffective = settings.enabled && Object.values(this._racePanels).some(\n (_) => _.expando.ineffective || _.settingItem.triggerButton.ineffective\n );\n }\n }\n );\n __publicField(this, "_racePanels");\n this._racePanels = this.host.game.diplomacy.races.filter((item) => !isNil(this.setting.races[item.name])).map(\n (race) => {\n var _a;\n return this._getTradeOption(\n this,\n this.setting.races[race.name],\n locale,\n settings,\n race.title,\n label2,\n race.name === ((_a = this.host.game.diplomacy.races.at(-2)) == null ? void 0 : _a.name)\n );\n }\n );\n const listRaces = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren(this._racePanels);\n listRaces.addChild(\n new SettingListItem(\n this,\n this.setting.feedLeviathans,\n this.host.engine.i18n("option.autofeed"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.autofeed")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.autofeed")\n ]);\n }\n }\n )\n );\n listRaces.addChild(\n new SettingsPanel(\n this,\n this.setting.tradeBlackcoin,\n new SettingTriggerListItem(\n this,\n this.setting.tradeBlackcoin,\n locale,\n this.host.engine.i18n("option.crypto"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.crypto")\n ]);\n },\n onRefreshRequest() {\n this.triggerButton.inactive = !this.setting.enabled || this.setting.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.trigger.crypto.promptTitle"),\n this.host.engine.i18n("ui.trigger.crypto.prompt", [\n this.host.renderAbsolute(this.setting.tradeBlackcoin.trigger, locale.selected)\n ]),\n this.host.renderAbsolute(this.setting.tradeBlackcoin.trigger),\n this.host.engine.i18n("ui.trigger.crypto.promptExplainer")\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n this.setting.tradeBlackcoin.trigger = this.host.parseAbsolute(value) ?? this.setting.tradeBlackcoin.trigger;\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.crypto")\n ]);\n }\n }\n )\n ).addChildrenContent([\n new BuyButton(this, this.setting.tradeBlackcoin, locale),\n new SellButton(this, this.setting.tradeBlackcoin, locale)\n ])\n );\n this.addChildContent(listRaces);\n const listAddition = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n });\n listAddition.addChild(new HeaderListItem(this, this.host.engine.i18n("ui.additional")));\n listAddition.addChild(\n new EmbassySettingsUi(this, this.setting.buildEmbassies, locale, settings)\n );\n listAddition.addChild(\n new SettingListItem(\n this,\n this.setting.unlockRaces,\n this.host.engine.i18n("ui.upgrade.races"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("ui.upgrade.races")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("ui.upgrade.races")\n ]);\n }\n }\n )\n );\n this.addChildContent(listAddition);\n }\n _getTradeOption(parent, option, locale, sectionSetting, label2, sectionLabel, delimiter2 = false, upgradeIndicator = false) {\n const element = new SettingLimitedTriggerListItem(parent, option, locale, label2, {\n delimiter: delimiter2,\n onCheck: () => {\n parent.host.engine.imessage("status.sub.enable", [label2]);\n },\n onLimitedCheck: () => {\n parent.host.engine.imessage("trade.limited", [label2]);\n },\n onLimitedUnCheck: () => {\n parent.host.engine.imessage("trade.unlimited", [label2]);\n },\n onRefreshTrigger: () => {\n element.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger", [\n option.trigger < 0 ? sectionSetting.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.blocked", [sectionLabel]) : `${parent.host.renderPercentage(sectionSetting.trigger, locale.selected, true)} (${parent.host.engine.i18n("ui.trigger.section.inherited")})` : parent.host.renderPercentage(option.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n option.trigger !== -1 ? parent.host.renderPercentage(option.trigger, locale.selected, true) : parent.host.engine.i18n("ui.trigger.section.inherited")\n ]),\n option.trigger !== -1 ? parent.host.renderPercentage(option.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n return;\n }\n option.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: () => {\n parent.host.engine.imessage("status.sub.disable", [label2]);\n },\n renderLabelTrigger: false,\n upgradeIndicator\n });\n const panel = new SettingsPanel(parent, option, element, {\n onRefreshRequest: () => {\n element.limitedButton.inactive = !option.enabled || !option.limited;\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = sectionSetting.enabled && option.enabled && sectionSetting.trigger === -1 && option.trigger === -1;\n panel.expando.ineffective = sectionSetting.enabled && option.enabled && !option.seasons.autumn.enabled && !option.seasons.spring.enabled && !option.seasons.summer.enabled && !option.seasons.winter.enabled;\n }\n }).addChildContent(\n new SeasonsList(parent, option.seasons, {\n onCheckSeason: (labelSeason) => {\n parent.host.engine.imessage("trade.season.enable", [ucfirst(label2), labelSeason]);\n },\n onUnCheckSeason: (labelSeason) => {\n parent.host.engine.imessage("trade.season.disable", [ucfirst(label2), labelSeason]);\n }\n })\n );\n return panel;\n }\n }\n const spacer = "_spacer_auis8_44";\n const ui = "_ui_auis8_49";\n const showActivity = "_showActivity_auis8_66";\n const styles = {\n spacer,\n ui,\n showActivity\n };\n class VillageSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${VillageSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.distribute");\n super(\n parent,\n settings,\n new SettingListItem(parent, settings, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n }\n }).addChildrenHead([new Container(parent, { classes: [stylesLabelListItem.fillSpace] })]),\n {\n onRefreshRequest: () => {\n this.expando.ineffective = settings.enabled && Object.values(settings.jobs).some((_) => _.enabled && 0 === _.max);\n }\n }\n );\n __publicField(this, "_hunt");\n __publicField(this, "_festivals");\n __publicField(this, "_promoteKittens");\n __publicField(this, "_promoteLeader");\n __publicField(this, "_electLeader");\n const listJobs = new SettingsList(this).addChildren(\n this.host.game.village.jobs.filter((item) => !isNil(this.setting.jobs[item.name])).map(\n (job) => this._getDistributeOption(\n this.setting.jobs[job.name],\n locale.selected,\n settings,\n job.title\n )\n )\n );\n this.addChildContent(listJobs);\n const listAddition = new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n });\n listAddition.addChild(new HeaderListItem(this, this.host.engine.i18n("ui.additional")));\n this._hunt = new SettingTriggerListItem(\n this,\n this.setting.hunt,\n locale,\n this.host.engine.i18n("option.hunt"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [this.host.engine.i18n("option.hunt")]);\n },\n onRefreshRequest: () => {\n this._hunt.triggerButton.inactive = !this.setting.hunt.enabled;\n this._hunt.triggerButton.ineffective = this.setting.enabled && this.setting.hunt.enabled && this.setting.hunt.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.trigger.prompt.percentage"),\n this.host.engine.i18n("ui.trigger.hunt.prompt", [\n this.host.renderPercentage(this.setting.hunt.trigger, locale.selected, true)\n ]),\n this.host.renderPercentage(this.setting.hunt.trigger),\n this.host.engine.i18n("ui.trigger.hunt.promptExplainer")\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n this.setting.hunt.trigger = this.host.parsePercentage(value);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [this.host.engine.i18n("option.hunt")]);\n }\n }\n );\n this._hunt.triggerButton.element.addClass(stylesButton.lastHeadAction);\n listAddition.addChild(this._hunt);\n this._festivals = new SettingListItem(\n this,\n this.setting.holdFestivals,\n this.host.engine.i18n("option.festival"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.festival")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.festival")\n ]);\n }\n }\n );\n listAddition.addChild(this._festivals);\n this._promoteKittens = new SettingTriggerListItem(\n this,\n this.setting.promoteKittens,\n locale,\n this.host.engine.i18n("option.promotekittens"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.promotekittens")\n ]);\n },\n onRefresh: () => {\n this._promoteKittens.triggerButton.inactive = !this.setting.promoteKittens.enabled;\n this._promoteKittens.triggerButton.ineffective = this.setting.enabled && this.setting.promoteKittens.enabled && this.setting.promoteKittens.trigger === -1;\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.trigger.promoteKittens.promptTitle"),\n this.host.engine.i18n("ui.trigger.promoteKittens.prompt", [\n this.host.renderPercentage(\n this.setting.promoteKittens.trigger,\n locale.selected,\n true\n )\n ]),\n this.host.renderPercentage(this.setting.promoteKittens.trigger),\n this.host.engine.i18n("ui.trigger.promoteKittens.promptExplainer")\n );\n if (value === void 0 || value === "" || value.startsWith("-")) {\n return;\n }\n this.setting.promoteKittens.trigger = this.host.parsePercentage(value);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.promotekittens")\n ]);\n }\n }\n );\n this._promoteKittens.triggerButton.element.addClass(stylesButton.lastHeadAction);\n listAddition.addChild(this._promoteKittens);\n this._promoteLeader = new SettingListItem(\n this,\n this.setting.promoteLeader,\n this.host.engine.i18n("option.promote"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [this.host.engine.i18n("option.promote")]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.promote")\n ]);\n }\n }\n );\n listAddition.addChild(this._promoteLeader);\n for (const option of this.setting.electLeader.job.options) {\n if (option.value === "any") {\n option.label = this.host.engine.i18n("option.elect.job.any");\n } else {\n option.label = this.host.engine.i18n(`$village.job.${option.value}`);\n }\n }\n for (const option of this.setting.electLeader.trait.options) {\n option.label = this.host.engine.i18n(`$village.trait.${option.value}`);\n }\n this._electLeader = new SettingListItem(\n this,\n this.setting.electLeader,\n this.host.engine.i18n("option.elect"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [this.host.engine.i18n("option.elect")]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [this.host.engine.i18n("option.elect")]);\n }\n }\n ).addChildren([\n new OptionsListItem(\n this,\n this.host.engine.i18n("option.elect.job"),\n this.setting.electLeader.job\n ),\n new OptionsListItem(\n this,\n this.host.engine.i18n("option.elect.trait"),\n this.setting.electLeader.trait\n )\n ]);\n listAddition.addChild(this._electLeader);\n this.addChildContent(listAddition);\n }\n _getDistributeOption(option, locale, sectionSetting, label2, delimiter2 = false) {\n const onSetMax = async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.max.distribute.prompt", [label2]),\n this.host.engine.i18n("ui.max.distribute.promptTitle", [\n label2,\n this.host.renderAbsolute(option.max, locale)\n ]),\n this.host.renderAbsolute(option.max),\n this.host.engine.i18n("ui.max.distribute.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.max = -1;\n return;\n }\n if (value === "0") {\n option.enabled = false;\n }\n option.max = this.host.parseAbsolute(value) ?? option.max;\n };\n const element = new SettingMaxListItem(this, option, label2, {\n delimiter: delimiter2,\n onCheck: (isBatchProcess) => {\n this.host.engine.imessage("status.sub.enable", [label2]);\n if (option.max === 0 && !isBatchProcess) {\n return onSetMax();\n }\n },\n onRefresh: () => {\n element.maxButton.inactive = !option.enabled || option.max === -1;\n element.maxButton.ineffective = sectionSetting.enabled && option.enabled && option.max === 0;\n },\n onRefreshMax: () => {\n element.maxButton.updateLabel(this.host.renderAbsolute(option.max));\n element.maxButton.element[0].title = option.max < 0 ? this.host.engine.i18n("ui.max.distribute.titleInfinite", [label2]) : option.max === 0 ? this.host.engine.i18n("ui.max.distribute.titleZero", [label2]) : this.host.engine.i18n("ui.max.distribute.title", [\n this.host.renderAbsolute(option.max),\n label2\n ]);\n },\n onSetMax,\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [label2]);\n }\n });\n element.maxButton.element.addClass(stylesButton.lastHeadAction);\n return element;\n }\n }\n class WorkshopCraftListItem extends SettingListItem {\n constructor(parent, setting2, locale, label2, options) {\n super(parent, setting2, label2, options);\n __publicField(this, "limitedButton");\n __publicField(this, "maxButton");\n __publicField(this, "triggerButton");\n this.limitedButton = new LimitedButton(parent, setting2, {\n ...options,\n classes: [stylesListItem.headAction]\n });\n this.maxButton = new MaxButton(parent, setting2, {\n alignment: "right",\n border: false,\n classes: [stylesButton.headAction],\n onClick: () => options.onSetMax.call(this),\n onRefresh: (options == null ? void 0 : options.onRefreshMax) ? () => {\n var _a;\n return (_a = options.onRefreshMax) == null ? void 0 : _a.call(this);\n } : void 0\n });\n this.triggerButton = new TriggerButton(parent, setting2, locale, {\n border: false,\n classes: [stylesButton.lastHeadAction],\n onClick: async () => {\n await options.onSetTrigger.call(this);\n },\n onRefresh: (options == null ? void 0 : options.onRefreshTrigger) ? () => {\n var _a;\n return (_a = options.onRefreshTrigger) == null ? void 0 : _a.call(this);\n } : void 0,\n renderLabel: (options == null ? void 0 : options.renderLabelTrigger) ?? true\n });\n this.addChildrenHead([\n new Container(parent, { classes: [stylesLabelListItem.fillSpace] }),\n this.limitedButton,\n this.maxButton,\n this.triggerButton\n ]);\n }\n toString() {\n return `[${WorkshopCraftListItem.name}#${this.componentId}]`;\n }\n }\n class UpgradeSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n const label2 = parent.host.engine.i18n("ui.upgrade.upgrades");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefreshTrigger() {\n this.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger", [\n settings.trigger === -1 ? parent.host.engine.i18n("ui.trigger.section.inactive") : parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger, locale.selected, true) : parent.host.engine.i18n("ui.infinity")\n ]),\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.trigger = -1;\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger === -1;\n this.settingItem.triggerButton.ineffective = settings.enabled && settings.trigger < 0 && Object.values(settings.upgrades).some((_) => _.enabled && _.trigger < 0);\n this.expando.ineffective = settings.enabled && !Object.values(settings.upgrades).some((_) => _.enabled);\n }\n }\n );\n const upgrades = this.host.game.workshop.upgrades.filter(\n (upgrade) => !isNil(this.setting.upgrades[upgrade.name])\n );\n const items = [];\n let lastLabel = upgrades[0].label;\n let lastElement;\n for (const upgrade of upgrades.sort(\n (a, b) => a.label.localeCompare(b.label, locale.selected)\n )) {\n const option = this.setting.upgrades[upgrade.name];\n const element = new SettingTriggerListItem(this, option, locale, upgrade.label, {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [upgrade.label]);\n },\n onRefreshRequest: () => {\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = settings.enabled && option.enabled && settings.trigger === -1 && option.trigger === -1;\n },\n onRefreshTrigger: () => {\n element.triggerButton.element[0].title = this.host.engine.i18n("ui.trigger", [\n option.trigger < 0 ? settings.trigger < 0 ? this.host.engine.i18n("ui.trigger.build.blocked", [label2]) : `${this.host.renderPercentage(settings.trigger, locale.selected, true)} (${this.host.engine.i18n("ui.trigger.section.inherited")})` : this.host.renderPercentage(option.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.trigger.prompt.percentage"),\n this.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n option.trigger !== -1 ? this.host.renderPercentage(option.trigger, locale.selected, true) : this.host.engine.i18n("ui.trigger.section.inherited")\n ]),\n option.trigger !== -1 ? this.host.renderPercentage(option.trigger) : "",\n this.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n return;\n }\n option.trigger = this.host.parsePercentage(value);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [upgrade.label]);\n },\n renderLabelTrigger: false\n });\n element.triggerButton.element.addClass(stylesButton.lastHeadAction);\n if (this.host.engine.localeSupportsFirstLetterSplits(locale.selected)) {\n if (lastLabel[0] !== upgrade.label[0]) {\n if (!isNil(lastElement)) {\n lastElement.element.addClass(stylesDelimiter.delimiter);\n }\n element.element.addClass(stylesLabelListItem.splitter);\n }\n }\n lastElement = element;\n items.push(element);\n lastLabel = upgrade.label;\n }\n this.addChildContent(new SettingsList(this).addChildren(items));\n }\n }\n class WorkshopSettingsUi extends SettingsPanel {\n constructor(parent, settings, locale) {\n console.debug(...cl(`Constructing ${WorkshopSettingsUi.name}`));\n const label2 = parent.host.engine.i18n("ui.craft");\n super(\n parent,\n settings,\n new SettingTriggerListItem(parent, settings, locale, label2, {\n onCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.enable", [label2]);\n },\n onRefreshTrigger() {\n this.triggerButton.element[0].title = parent.host.engine.i18n("ui.trigger.section", [\n settings.trigger < 0 ? parent.host.engine.i18n("ui.trigger.section.inactive") : parent.host.renderPercentage(settings.trigger, locale.selected, true)\n ]);\n },\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n parent,\n parent.host.engine.i18n("ui.trigger.prompt.percentage"),\n parent.host.engine.i18n("ui.trigger.section.prompt", [\n label2,\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger, locale.selected, true) : parent.host.engine.i18n("ui.infinity")\n ]),\n settings.trigger !== -1 ? parent.host.renderPercentage(settings.trigger) : "",\n parent.host.engine.i18n("ui.trigger.section.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n settings.trigger = -1;\n return;\n }\n settings.trigger = parent.host.parsePercentage(value);\n },\n onUnCheck: (_isBatchProcess) => {\n parent.host.engine.imessage("status.auto.disable", [label2]);\n },\n renderLabelTrigger: false\n }),\n {\n onRefreshRequest: () => {\n this.settingItem.triggerButton.inactive = !settings.enabled || settings.trigger === -1;\n this.settingItem.triggerButton.ineffective = settings.enabled && settings.trigger < 0 && Object.values(settings.resources).some((_) => _.enabled && 0 !== _.max && _.trigger < 0);\n }\n }\n );\n __publicField(this, "_crafts");\n let excludeCraftsArray = [];\n if (!game.challenges.getChallenge("ironWill").active) {\n this.setting.resources.bloodstone.enabled = false;\n this.setting.resources.tMythril.enabled = false;\n excludeCraftsArray = ["bloodstone", "tMythril"];\n }\n const preparedCrafts = this.host.game.workshop.crafts.filter(\n (item) => !excludeCraftsArray.includes(item.name) && !isNil(this.setting.resources[item.name])\n ).map((resource) => [this.setting.resources[resource.name], ucfirst(resource.label)]);\n this._crafts = [];\n for (const [option, label22] of preparedCrafts) {\n const onSetMax = async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.max.craft.prompt", [label22]),\n this.host.engine.i18n("ui.max.craft.promptTitle", [\n label22,\n this.host.renderAbsolute(option.max, locale.selected)\n ]),\n this.host.renderAbsolute(option.max),\n this.host.engine.i18n("ui.max.craft.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.max = -1;\n return;\n }\n if (value === "0") {\n option.enabled = false;\n }\n option.max = this.host.parseAbsolute(value) ?? option.max;\n };\n const element = new WorkshopCraftListItem(this, option, locale, label22, {\n delimiter: option.resource === "kerosene" || option.resource === "blueprint",\n onCheck: (isBatchProcess) => {\n this.host.engine.imessage("status.sub.enable", [label22]);\n if (option.max === 0 && !isBatchProcess) {\n return onSetMax();\n }\n },\n onLimitedCheck: () => {\n this.host.engine.imessage("craft.limited", [label22]);\n },\n onLimitedUnCheck: () => {\n this.host.engine.imessage("craft.unlimited", [label22]);\n },\n onRefreshMax: () => {\n element.maxButton.updateLabel(this.host.renderAbsolute(option.max));\n element.maxButton.element[0].title = option.max < 0 ? this.host.engine.i18n("ui.max.craft.titleInfinite", [label22]) : option.max === 0 ? this.host.engine.i18n("ui.max.craft.titleZero", [label22]) : this.host.engine.i18n("ui.max.craft.title", [\n this.host.renderAbsolute(option.max),\n label22\n ]);\n },\n onRefreshRequest: () => {\n element.limitedButton.inactive = !option.enabled || !option.limited;\n element.maxButton.inactive = !option.enabled || option.max === -1;\n element.maxButton.ineffective = settings.enabled && option.enabled && option.max === 0;\n element.triggerButton.inactive = !option.enabled || option.trigger === -1;\n element.triggerButton.ineffective = settings.enabled && option.enabled && settings.trigger === -1 && option.trigger === -1;\n },\n onRefreshTrigger: () => {\n element.triggerButton.element[0].title = this.host.engine.i18n("ui.trigger", [\n option.trigger < 0 ? settings.trigger < 0 ? this.host.engine.i18n("ui.trigger.build.blocked", [label22]) : `${this.host.renderPercentage(settings.trigger, locale.selected, true)} (${this.host.engine.i18n("ui.trigger.build.inherited")})` : this.host.renderPercentage(option.trigger, locale.selected, true)\n ]);\n },\n onSetMax,\n onSetTrigger: async () => {\n const value = await Dialog.prompt(\n this,\n this.host.engine.i18n("ui.trigger.prompt.percentage"),\n this.host.engine.i18n("ui.trigger.section.prompt", [\n label22,\n option.trigger !== -1 ? this.host.renderPercentage(option.trigger, locale.selected, true) : this.host.engine.i18n("ui.trigger.build.inherited")\n ]),\n option.trigger !== -1 ? this.host.renderPercentage(option.trigger) : "",\n this.host.engine.i18n("ui.trigger.build.promptExplainer")\n );\n if (value === void 0) {\n return;\n }\n if (value === "" || value.startsWith("-")) {\n option.trigger = -1;\n return;\n }\n option.trigger = this.host.parsePercentage(value);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [label22]);\n },\n renderLabelTrigger: false\n });\n this._crafts.push(element);\n if (option.resource === "ship") {\n this._crafts.push(\n new SettingListItem(\n this,\n this.setting.shipOverride,\n this.host.engine.i18n("option.shipOverride"),\n {\n onCheck: () => {\n this.host.engine.imessage("status.sub.enable", [\n this.host.engine.i18n("option.shipOverride")\n ]);\n },\n onUnCheck: () => {\n this.host.engine.imessage("status.sub.disable", [\n this.host.engine.i18n("option.shipOverride")\n ]);\n },\n upgradeIndicator: true\n }\n )\n );\n }\n }\n const listCrafts = new SettingsList(this, {\n onReset: () => {\n this.setting.load({ resources: new WorkshopSettings().resources });\n }\n }).addChildren(this._crafts);\n this.addChildContent(listCrafts);\n this.addChildContent(\n new SettingsList(this, {\n hasDisableAll: false,\n hasEnableAll: false\n }).addChildren([new UpgradeSettingsUi(this, this.setting.unlockUpgrades, locale)])\n );\n }\n }\n class UserInterface extends UiComponent {\n constructor(host) {\n console.debug(...cl(`Constructing ${UserInterface.name}`));\n super({ host }, {});\n __publicField(this, "showActivity");\n __publicField(this, "_engineUi");\n __publicField(this, "_sections");\n __publicField(this, "stateManagementUi");\n __publicField(this, "_refreshTimeout");\n const engine = host.engine;\n this._engineUi = new EngineSettingsUi(this, engine.settings);\n this.stateManagementUi = new StateManagementUi(\n this,\n engine.settings.states,\n engine.settings.locale\n );\n this._sections = [\n new BonfireSettingsUi(this, engine.bonfireManager.settings, engine.settings.locale),\n new VillageSettingsUi(this, engine.villageManager.settings, engine.settings.locale),\n new ScienceSettingsUi(this, engine.scienceManager.settings, engine.settings.locale),\n new WorkshopSettingsUi(this, engine.workshopManager.settings, engine.settings.locale),\n new ResourcesSettingsUi(this, engine.settings.resources, engine.settings.locale),\n new TradeSettingsUi(this, engine.tradeManager.settings, engine.settings.locale),\n new ReligionSettingsUi(this, engine.religionManager.settings, engine.settings.locale),\n new SpaceSettingsUi(this, engine.spaceManager.settings, engine.settings.locale),\n new TimeSettingsUi(this, engine.timeManager.settings, engine.settings.locale),\n new TimeControlSettingsUi(this, engine.timeControlManager.settings, engine.settings.locale),\n new LogFiltersSettingsUi(this, engine.settings.filters),\n this.stateManagementUi,\n new InternalsUi(this, engine.settings, engine.settings.locale)\n ];\n this.parent = this;\n this.element = $("<div/>").addClass("kitten-scientists").addClass(styles.ui);\n for (const section of [this._engineUi, ...this._sections]) {\n this.addChild(section);\n }\n const optionsListElement = $("<ul/>");\n optionsListElement.append(this._engineUi.element);\n for (const section of this._sections) {\n optionsListElement.append(section.element);\n }\n this.element.append(optionsListElement);\n const expando = this._engineUi.expando;\n let sectionsVisible = false;\n expando.element.on("click", () => {\n sectionsVisible = !sectionsVisible;\n for (const section of this._sections) {\n section.toggle(sectionsVisible, true);\n }\n });\n let panelsOpen = 0;\n for (const section of this._sections) {\n section.element[0].addEventListener("panelHidden", () => {\n --panelsOpen;\n if (panelsOpen === 0) {\n sectionsVisible = false;\n }\n if (!sectionsVisible) {\n expando.setCollapsed();\n }\n });\n section.element[0].addEventListener("panelShown", () => {\n ++panelsOpen;\n sectionsVisible = true;\n expando.setExpanded();\n });\n }\n this.showActivity = $("<span/>", {\n html: `<svg style="width: 18px; height: 18px;" viewBox="0 -960 960 960" fill="currentColor"><path d="${Icons.Summary}"/></svg>`,\n title: host.engine.i18n("summary.show")\n }).addClass(styles.showActivity);\n this.showActivity.on("click", () => {\n host.engine.displayActivitySummary();\n });\n $("#clearLog").prepend(this.showActivity);\n const usingKSColumn = engine.settings.ksColumn.enabled && game.colorScheme !== "sleek";\n if (usingKSColumn) {\n $("#rightColumn").after(\n `<div id="ksColumn" class="column"><span class="${styles.spacer}"></span></div>`\n );\n } else {\n $("#ksColumn").remove();\n }\n const right = $(usingKSColumn ? "#ksColumn" : "#rightColumn");\n if (right.length === 0) {\n const optionsPageContent = $("#optionsPage .full-screen-position .page .page-content");\n if (optionsPageContent.length === 0) {\n console.warn(...cl("Unable to find right column to inject UI into. Running headless."));\n } else {\n optionsPageContent.append(this.element);\n this.element.attr("style", "border-top:1px solid grey; padding:15px");\n }\n } else {\n right.prepend(this.element);\n }\n this.element = this.element;\n this._needsRefresh = false;\n }\n toString() {\n return `[${UserInterface.name}#${this.componentId}]`;\n }\n destroy() {\n if (this._refreshTimeout !== void 0) {\n UserScriptLoader.window.clearTimeout(this._refreshTimeout);\n this._refreshTimeout = void 0;\n }\n this.showActivity.remove();\n this.element.remove();\n }\n requestRefresh(_withChildren = true, depth = 0, _trace = false) {\n if (this._needsRefresh) {\n if (this._refreshTimeout === void 0) {\n console.error(...cl("User interface claims to have a refresh pending, but there isn\'t."));\n }\n return;\n }\n this._refreshTimeout = UserScriptLoader.window.setTimeout(() => {\n const [_, duration] = measure(() => this.refresh());\n console.info(...cl(`UI refresh took ${formatMilliseconds(duration)}.`));\n this._refreshTimeout = void 0;\n }, 0);\n super.requestRefresh(true, depth, false);\n }\n forceFullRefresh() {\n console.warn(...cl("Forcing refresh on all user interface components..."));\n this.requestRefresh();\n console.warn(...cl("Refresh on all user interface components enforced."));\n }\n }\n const ksVersion = (prefix = "") => {\n if (isNil("2.0.0-beta.11-live")) {\n throw Error("Build error: RELEASE_VERSION is not defined.");\n }\n return `${prefix}${"2.0.0-beta.11-live"}`;\n };\n class KittenScientists {\n constructor(game2, i18nEngine, gameLanguage = "en", engineState) {\n __publicField(this, "game");\n /**\n * A function in the game that allows to retrieve translated messages.\n *\n * Ideally, you should never access this directly and instead use the\n * i18n interface provided by `Engine`.\n */\n __publicField(this, "i18nEngine");\n __publicField(this, "_userInterface");\n __publicField(this, "engine");\n __publicField(this, "_gameBeforeSaveHandle");\n __publicField(this, "_serverLoadHandle");\n __publicField(this, "_saveManager", {\n load: (saveData) => {\n console.info(...cl("Looking for Kitten Scientists engine state in save data..."));\n const state = UserScriptLoader.tryEngineStateFromSaveData("ks", saveData);\n if (!state) {\n console.info(...cl("The Kittens Game save data did not contain a script state."));\n return;\n }\n console.info(...cl("Found Kitten Scientists engine state in save data."));\n this.engine.stateLoad(state);\n this.refreshEntireUserInterface();\n },\n resetState: () => null,\n save: (_saveData) => {\n }\n });\n var _a;\n console.info(\n ...cl(`Kitten Scientists ${ksVersion("v")} constructed. Checking for previous instances...`)\n );\n if ("kittenScientists" in UserScriptLoader.window) {\n console.warn(...cl("Detected existing KS instance. Trying to unload it..."));\n (_a = UserScriptLoader.window.kittenScientists) == null ? void 0 : _a.unload();\n }\n console.info(...cl(`You are on the \'${String("fixed")}\' release channel.`));\n this.game = game2;\n this.i18nEngine = i18nEngine;\n try {\n this.engine = new Engine(this, gameLanguage);\n this._userInterface = new UserInterface(this);\n } catch (error) {\n console.error(...cl("Failed to construct core components.", error));\n if (typeof GM !== "undefined") {\n console.warn(...cl("Detected running in Greasemonkey."));\n }\n throw error;\n }\n if (!isNil(engineState)) {\n this.setSettings(engineState);\n } else {\n this._userInterface.stateManagementUi.loadAutoSave();\n }\n }\n rebuildUi() {\n this._userInterface.destroy();\n this._userInterface = new UserInterface(this);\n this._userInterface.forceFullRefresh();\n }\n /**\n * Runs some validations against the game to determine if internal control\n * structures still match up with expectations.\n * Issues should be logged to the console.\n */\n validateGame() {\n ScienceSettings.validateGame(this.game, this.engine.scienceManager.settings);\n SpaceSettings.validateGame(this.game, this.engine.spaceManager.settings);\n WorkshopSettings.validateGame(this.game, this.engine.workshopManager.settings);\n }\n /**\n * Removes Kitten Scientists from the browser.\n */\n unload() {\n console.warn(...cl("Unloading Kitten Scientists..."));\n this.engine.stop();\n this._userInterface.destroy();\n $("#ks-styles").remove();\n if (this._gameBeforeSaveHandle !== void 0) {\n UserScriptLoader.window.dojo.unsubscribe(this._gameBeforeSaveHandle);\n this._gameBeforeSaveHandle = void 0;\n }\n if (this._serverLoadHandle !== void 0) {\n UserScriptLoader.window.dojo.unsubscribe(this._serverLoadHandle);\n this._gameBeforeSaveHandle = void 0;\n }\n const managerIndex = this.game.managers.indexOf(this._saveManager);\n if (-1 < managerIndex) {\n this.game.managers.splice(managerIndex, 1);\n }\n UserScriptLoader.window.kittenScientists = void 0;\n console.warn(...cl("Kitten Scientists have been unloaded!"));\n }\n /**\n * Start the user script after loading and configuring it.\n */\n run() {\n this.game.console.maxMessages = 1e3;\n this.refreshEntireUserInterface();\n if (this.engine.settings.enabled) {\n this.engine.start(true);\n }\n this.engine.imessage("status.ks.init");\n this.runUpdateCheck().catch(redirectErrorsToConsole(console));\n if (this._gameBeforeSaveHandle !== void 0) {\n UserScriptLoader.window.dojo.unsubscribe(this._gameBeforeSaveHandle);\n this._gameBeforeSaveHandle = void 0;\n }\n this._gameBeforeSaveHandle = UserScriptLoader.window.dojo.subscribe(\n "game/beforesave",\n (saveData) => {\n console.info(...cl("Injecting Kitten Scientists engine state into save data..."));\n const state = this.getSettings();\n saveData.ks = { state: [state] };\n this._userInterface.stateManagementUi.storeAutoSave(state);\n document.dispatchEvent(\n new CustomEvent("ks.reportSavegame", { detail: saveData })\n );\n }\n );\n if (this._serverLoadHandle !== void 0) {\n UserScriptLoader.window.dojo.unsubscribe(this._serverLoadHandle);\n this._gameBeforeSaveHandle = void 0;\n }\n this._serverLoadHandle = UserScriptLoader.window.dojo.subscribe(\n "server/load",\n (saveData) => {\n const state = UserScriptLoader.tryEngineStateFromSaveData("ks", saveData);\n if (!state) {\n console.info(\n ...cl(\n "The Kittens Game save data did not contain a script state. Trying to load Auto-Save settings..."\n )\n );\n return;\n }\n console.info(...cl("Found! Loading settings..."));\n this.engine.stateLoad(state);\n }\n );\n }\n /**\n * Check which versions of KS are currently published.\n */\n async runUpdateCheck() {\n {\n console.debug(...cl("No update check on \'fixed\' release channel."));\n return;\n }\n }\n /**\n * Requests the user interface to refresh.\n */\n refreshEntireUserInterface() {\n console.info(...cl("Requesting entire user interface to be refreshed."));\n this._userInterface.forceFullRefresh();\n }\n /**\n * Turns a string like 52.7 into the number 52.7\n * @param value - String representation of an absolute value.\n * @returns A number between 0 and Infinity, where Infinity is represented as -1.\n */\n parseFloat(value) {\n if (value === null || value === "") {\n return null;\n }\n const hasSuffix = /[KMGTP]$/i.test(value);\n const baseValue = value.substring(0, value.length - (hasSuffix ? 1 : 0));\n let numericValue = value.includes("e") || hasSuffix ? Number.parseFloat(baseValue) : Number.parseInt(baseValue);\n if (hasSuffix) {\n const suffix = value.substring(value.length - 1).toUpperCase();\n numericValue = numericValue * 1e3 ** ["", "K", "M", "G", "T", "P"].indexOf(suffix);\n }\n if (numericValue === Number.POSITIVE_INFINITY || numericValue < 0) {\n numericValue = -1;\n }\n return numericValue;\n }\n parseAbsolute(value) {\n const floatValue = this.parseFloat(value);\n return floatValue !== null ? Math.round(floatValue) : null;\n }\n /**\n * Turns a string like 52.7 into the number 0.527\n * @param value - String representation of a percentage.\n * @returns A number between 0 and 1 representing the described percentage.\n */\n parsePercentage(value) {\n const cleanedValue = value.trim().replace(/%$/, "");\n return Math.max(0, Math.min(1, Number.parseFloat(cleanedValue) / 100));\n }\n /**\n * Turns a number into a game-native string representation.\n * Infinity, either by actual value or by -1 representation, is rendered as a symbol.\n * @param value - The number to render as a string.\n * @param host - The host instance which we can use to let the game render values for us.\n * @returns A string representing the given number.\n */\n renderAbsolute(value, locale = "invariant") {\n if (value < 0 || value === Number.POSITIVE_INFINITY) {\n return "∞";\n }\n return locale !== "invariant" && Math.floor(Math.log10(value)) < 9 ? new Intl.NumberFormat(locale, { maximumFractionDigits: 0, style: "decimal" }).format(value) : this.game.getDisplayValueExt(value, false, false);\n }\n /**\n * Turns a number like 0.527 into a string like 52.7\n * @param value - The number to render as a string.\n * @param locale - The locale in which to render the percentage.\n * @param withUnit - Should the percentage sign be included in the output?\n * @returns A string representing the given percentage.\n */\n renderPercentage(value, locale = "invariant", withUnit) {\n if (value < 0 || value === Number.POSITIVE_INFINITY) {\n return "∞";\n }\n return locale !== "invariant" ? new Intl.NumberFormat(locale, { style: "percent" }).format(value) : `${this.game.getDisplayValueExt(value * 100, false, false)}${withUnit ? "%" : ""}`;\n }\n renderFloat(value, locale = "invariant") {\n if (value < 0 || value === Number.POSITIVE_INFINITY) {\n return "∞";\n }\n return locale !== "invariant" ? new Intl.NumberFormat(locale, { style: "decimal" }).format(value) : this.game.getDisplayValueExt(value, false, false);\n }\n //#region Settings\n /**\n * Encodes an engine states into a string.\n *\n * @param settings The engine state to encode.\n * @param compress Should we use LZString compression?\n * @returns The settings encoded into a string.\n */\n static encodeSettings(settings, compress = true) {\n const settingsString = JSON.stringify(settings);\n return compress ? UserScriptLoader.window.LZString.compressToBase64(settingsString) : settingsString;\n }\n /**\n * Given a serialized engine state, attempts to deserialize that engine state.\n * Assumes the input has been compressed with LZString, will accept uncompressed.\n *\n * @param compressedSettings An engine state that has previously been serialized to a string.\n * @returns The engine state, if valid.\n */\n static decodeSettings(compressedSettings) {\n try {\n const naiveParse = JSON.parse(compressedSettings);\n return KittenScientists.unknownAsEngineStateOrThrow(naiveParse);\n } catch (_error) {\n }\n if (compressedSettings.match(/\\r?\\n/)) {\n throw new InvalidOperationError("Multi-line non-JSON input can\'t be decoded.");\n }\n const settingsString = UserScriptLoader.window.LZString.decompressFromBase64(compressedSettings);\n const parsed = JSON.parse(settingsString);\n return KittenScientists.unknownAsEngineStateOrThrow(parsed);\n }\n /**\n * Retrieves the state from the engine.\n *\n * @returns The engine state.\n */\n getSettings() {\n return this.engine.stateSerialize();\n }\n getSettingsAsJson() {\n return JSON.stringify(this.getSettings());\n }\n /**\n * Updates the engine with a new state.\n *\n * @param settings The engine state to apply.\n */\n setSettings(settings) {\n console.info(...cl("Loading engine state..."));\n const requiresUiRebuild = this.engine.settings.ksColumn.enabled !== settings.engine.ksColumn.enabled;\n this.engine.stateLoad(settings);\n if (requiresUiRebuild) {\n this.rebuildUi();\n }\n this._userInterface.refresh(true);\n }\n /**\n * Loads an encoded state into the engine.\n *\n * @param encodedSettings The encoded settings.\n */\n importSettingsFromString(encodedSettings) {\n const settings = KittenScientists.decodeSettings(encodedSettings);\n this.setSettings(settings);\n }\n /**\n * Copies an engine state to the clipboard.\n *\n * @param settings The engine state to copy to the clipboard.\n * The default is this engine\'s current state.\n * @param compress Should the state be compressed?\n */\n async copySettings(settings = this.getSettings(), compress = true) {\n const encodedSettings = KittenScientists.encodeSettings(settings, compress);\n await UserScriptLoader.window.navigator.clipboard.writeText(encodedSettings);\n }\n /**\n * Determines if an object is an engine state, and throws an\n * exception otherwise.\n *\n * @param subject The object that is hopefully an engine state.\n * @param subject.v The version in the engine state.\n * @returns An engine state.\n */\n static unknownAsEngineStateOrThrow(subject) {\n const v = subject.v;\n if (!isNil(v) && typeof v === "string") {\n if (v.startsWith("2")) {\n return subject;\n }\n }\n throw new Error("Not a valid engine state.");\n }\n //#endregion\n //#region SaveManager\n installSaveManager() {\n console.info(...cl("Installing save game manager..."));\n this.game.managers.push(this._saveManager);\n }\n //#endregion\n }\n (async () => {\n const userScript = await new UserScriptLoader().waitForGame(KittenScientists, "ks");\n UserScriptLoader.window.kittenScientists = userScript;\n userScript.validateGame();\n userScript.run();\n })().catch(console.error);\n});\n\n(function() {\n "use strict";\n try {\n if (typeof document != "undefined") {\n var elementStyle = document.createElement("style");\n elementStyle.id = "ks-styles";\n elementStyle.appendChild(document.createTextNode(\'._label_1nlev_1 {\\n align-content: center;\\n display: inline-block;\\n flex: 0 1 fit-content;\\n opacity: 0.8;\\n\\n white-space: nowrap;\\n\\n transition: 0.3s;\\n\\n &:hover {\\n opacity: 1;\\n }\\n}\\n\\n._splitter_1nlev_16 ._label_1nlev_1::first-letter {\\n font-weight: bold;\\n}\\n\\n._iconLabel_1nlev_20 {\\n display: inline-block;\\n margin-right: 4px;\\n margin-left: 2px;\\n vertical-align: middle;\\n}\\n._fillSpace_1nlev_26 {\\n flex: 1;\\n}\\n._delimiter_16hnh_1 {\\n margin-bottom: 10px;\\n}\\n._head_wr1pj_1 {\\n display: flex;\\n align-items: stretch;\\n flex-direction: row;\\n justify-content: flex-start;\\n width: 100%;\\n\\n transition: 0.3s;\\n\\n > ._headFlexItem_wr1pj_10 {\\n flex: 1;\\n margin-right: 8px;\\n }\\n}\\n._setting_1ndg5_1 {\\n border-bottom: 1px solid transparent;\\n\\n transition: border-bottom 0.3s;\\n\\n ._checkbox_1ndg5_6 {\\n margin: 1px 5px 2px 2px;\\n }\\n\\n ._panelContent_1ndg5_10 {\\n border-left: 1px dashed grey;\\n padding-left: 16px;\\n margin-left: 8px;\\n margin-top: 1px;\\n opacity: 0.5;\\n\\n &._hidden_1ndg5_17 {\\n display: none;\\n }\\n }\\n\\n &._checked_1ndg5_22 > ._panelContent_1ndg5_10 {\\n opacity: 1;\\n }\\n\\n &._expanded_1ndg5_26 {\\n margin-bottom: 10px;\\n }\\n\\n &:not(._expanded_1ndg5_26):hover {\\n border-bottom: 1px dashed rgba(160, 160, 160, 0.2);\\n }\\n\\n &._readonly_1ndg5_34 {\\n cursor: default;\\n pointer-events: none;\\n }\\n}\\n@keyframes _hail-rainbow_q7zpt_1 {\\n 0%,\\n 100% {\\n color: red;\\n text-shadow: 0 0 10px red;\\n }\\n 33% {\\n color: #888;\\n text-shadow: 0 0 10px yellow;\\n }\\n 66% {\\n color: white;\\n text-shadow: 0 0 10px black;\\n }\\n}\\n\\n._iconButton_q7zpt_17 {\\n cursor: pointer;\\n display: block;\\n padding-right: 3px;\\n line-height: 0;\\n opacity: 0.8;\\n transition: 0.3s;\\n\\n &:hover {\\n opacity: 1;\\n }\\n\\n &._inactive_q7zpt_29 {\\n opacity: 0.4;\\n\\n &:hover {\\n opacity: 0.6;\\n }\\n }\\n\\n &._ineffective_q7zpt_37 {\\n color: red;\\n animation: _hail-rainbow_q7zpt_1 5s linear infinite;\\n }\\n}\\n\\n._button_q7zpt_43 {\\n align-items: end;\\n cursor: pointer;\\n display: flex;\\n opacity: 0.8;\\n transition: 0.3s;\\n\\n &:hover {\\n opacity: 1;\\n }\\n\\n &._inactive_q7zpt_29 {\\n opacity: 0.4;\\n\\n &:hover {\\n opacity: 0.6;\\n }\\n }\\n\\n &._ineffective_q7zpt_37 {\\n color: red;\\n animation: _hail-rainbow_q7zpt_1 5s linear infinite;\\n }\\n\\n &._readonly_q7zpt_67 {\\n cursor: default;\\n pointer-events: none;\\n }\\n\\n ._buttonIcon_q7zpt_72 {\\n margin: 0 2px 0 0;\\n vertical-align: sub;\\n }\\n\\n &._alignRight_q7zpt_77 {\\n justify-content: end;\\n }\\n\\n &._large_q7zpt_81 {\\n padding: 5px 10px;\\n }\\n\\n &._bordered_q7zpt_85 {\\n border: 1px solid rgba(180, 180, 180, 0.2);\\n\\n &:not(._large_q7zpt_81) {\\n padding: 0 2px;\\n }\\n\\n &:hover {\\n border: 1px solid rgba(180, 180, 180, 1);\\n }\\n }\\n\\n &._headAction_q7zpt_97 {\\n min-width: 50px;\\n }\\n &._lastHeadAction_q7zpt_100 {\\n padding-right: 20px;\\n }\\n\\n &._consumeButton_q7zpt_104 {\\n border: 1px solid transparent;\\n }\\n &._stockButton_q7zpt_107 {\\n border: 1px solid transparent;\\n }\\n}\\n\\n._button_q7zpt_43:not(._bordered_q7zpt_85) + ._button_q7zpt_43:not(._bordered_q7zpt_85):before {\\n content: "";\\n display: inline-block;\\n height: 1em;\\n border-left: 1px solid transparent;\\n}\\n._button_q7zpt_43:not(._bordered_q7zpt_85):not(._inactive_q7zpt_29)._alignRight_q7zpt_77 + ._button_q7zpt_43:not(._bordered_q7zpt_85):not(._inactive_q7zpt_29):before {\\n content: "";\\n display: inline-block;\\n height: 1em;\\n border-left: 1px solid rgba(180, 180, 180, 0.4);\\n}\\n._listContainer_1kxbq_1 {\\n margin-bottom: 4px;\\n}\\n\\n._itemsList_1kxbq_5 {\\n user-select: none;\\n}\\n\\n._list_1kxbq_1 ~ ._listTools_1kxbq_9 {\\n border-top: 1px dotted rgba(128, 128, 128, 0.3);\\n margin-left: 0px;\\n padding-top: 2px;\\n}\\n._list_1kxbq_1 ~ ._listTools_1kxbq_9 * {\\n display: inline-block;\\n}\\n._expandoButton_l1ukp_1:not(._expanded_l1ukp_1) ._up_l1ukp_1 {\\n display: none;\\n}\\n._expandoButton_l1ukp_1:not(._expanded_l1ukp_1) ._down_l1ukp_4 {\\n opacity: 0.6;\\n\\n &:hover {\\n opacity: 1;\\n }\\n}\\n._expandoButton_l1ukp_1._expanded_l1ukp_1 ._down_l1ukp_4 {\\n display: none;\\n}\\n#gamePageContainer .dialog.help ._dialog_1276o_1 {\\n display: flex;\\n flex-direction: column;\\n height: fit-content !important;\\n box-shadow: none !important;\\n\\n ._close_1276o_7 {\\n position: absolute;\\n top: 10px;\\n right: 15px;\\n }\\n}\\n._explainer_1idu3_1 {\\n color: #888;\\n display: inline-block;\\n min-width: 100px;\\n user-select: none;\\n padding: 4px;\\n white-space: break-spaces;\\n}\\n._explainer_1idu3_1 p {\\n margin: 0;\\n}\\n._header_19ql8_1 {\\n display: block;\\n margin-bottom: 3px;\\n min-width: 100px;\\n\\n border-bottom: 1px dashed rgba(255, 255, 255, 0.1);\\n\\n font-weight: bold;\\n user-select: none;\\n}\\n._toolbar_1654f_1 {\\n display: flex;\\n flex-direction: row;\\n\\n padding: 0 0 2px 0;\\n margin: 0 0 3px 0;\\n}\\n._toolbar_1654f_1 > * {\\n margin: 0 3px 0 0;\\n}\\n._maxButton_133h2_1 {\\n padding-right: 5px;\\n padding-top: 2px;\\n}\\n._fieldset_tfwil_1 {\\n border-bottom: none;\\n border-right: none;\\n border-top: none;\\n}\\n._textButton_1mv97_1 {\\n display: inline-block;\\n white-space: nowrap;\\n opacity: 0.8;\\n\\n cursor: pointer;\\n user-select: none;\\n}\\n._textButton_1mv97_1:hover {\\n opacity: 1;\\n}\\n@keyframes _scale_6c09s_1 {\\n 0% {\\n scale: 0.5;\\n opacity: 0;\\n }\\n 50% {\\n scale: 1;\\n opacity: 1;\\n }\\n 100% {\\n scale: 2;\\n opacity: 0;\\n }\\n}\\n\\n._active_6c09s_16 {\\n text-shadow: rgba(128, 128, 128, 0.8) 0 0 15px;\\n position: relative;\\n\\n &::after,\\n &::before {\\n display: inline-block;\\n width: 1em;\\n height: 100%;\\n position: absolute;\\n right: -1.5em;\\n scale: 0;\\n text-align: center;\\n transform-origin: center;\\n }\\n\\n &::after {\\n content: attr(data-ks-active-from);\\n animation: _scale_6c09s_1 8s linear infinite;\\n }\\n\\n &::before {\\n content: attr(data-ks-active-to);\\n animation: _scale_6c09s_1 8s linear infinite;\\n animation-delay: 4s;\\n }\\n}\\n._buyButton_10eul_1 {\\n display: inline-block;\\n padding-right: 10px;\\n min-width: 86px;\\n}\\n._sellButton_1tmvd_1 {\\n display: inline-block;\\n padding-right: 10px;\\n min-width: 86px;\\n}\\n#ksColumn {\\n min-width: 250px;\\n max-width: 440px;\\n vertical-align: top;\\n padding-left: 8px;\\n top: 20px;\\n position: relative;\\n overflow-y: auto;\\n}\\n\\n#footerLinks {\\n display: flex;\\n flex-direction: column;\\n position: fixed;\\n text-align: right;\\n line-height: 0;\\n right: -5px !important;\\n margin-bottom: 1em;\\n\\n a {\\n line-height: 1;\\n padding-right: 10px;\\n opacity: 0.5;\\n transition: 0.3s;\\n text-decoration: none;\\n text-transform: lowercase;\\n\\n &:hover {\\n opacity: 1;\\n }\\n }\\n}\\n#crowdjet-expand-container {\\n position: fixed !important;\\n bottom: 10px !important;\\n right: -10px !important;\\n opacity: 0.5;\\n\\n &:hover {\\n opacity: 1;\\n }\\n}\\n\\n._spacer_auis8_44 {\\n display: block;\\n margin-bottom: 100px;\\n}\\n\\n._ui_auis8_49 {\\n margin: 5px 0 10px 0;\\n padding-right: 10px;\\n\\n ul {\\n list-style: none;\\n margin: 0;\\n padding: 0;\\n }\\n\\n /* Rules needed to enable stock warning. */\\n #_toggle-list-resources_auis8_1 ._stockWarn_auis8_60 *,\\n #_toggle-reset-list-resources_auis8_1 ._stockWarn_auis8_60 * {\\n color: #dd1e00;\\n }\\n}\\n\\n._showActivity_auis8_66 {\\n cursor: pointer;\\n display: inline-block;\\n vertical-align: middle;\\n}\\n\\n/* Ensure the right column gets a scrollbar, when our content extends it too far down. */\\n#game #rightColumn {\\n overflow-y: auto;\\n\\n /* Fix some double-scrollbar issues in the right column, when KS is loaded. */\\n #rightTabLog {\\n overflow-y: visible;\\n\\n #gameLog {\\n height: auto;\\n min-height: auto;\\n overflow-y: visible;\\n }\\n }\\n}\\n\\n#game .res-row .res-cell.ks-stock-above {\\n color: green;\\n}\\n#game .res-row .res-cell.ks-stock-below {\\n color: red;\\n}\'));\n document.head.appendChild(elementStyle);\n }\n } catch (e) {\n console.error("vite-plugin-css-injected-by-js", e);\n }\n})();\n';
|
|
105
|
+
nodeScript.type = "application/javascript";
|
|
106
|
+
document.body.appendChild(nodeScript);
|
|
107
|
+
}
|
|
108
|
+
})().catch(redirectErrorsToConsole(console));
|
|
109
|
+
});
|